All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.addthis.meshy.service.file.FileSource Maven / Gradle / Ivy

/*
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.addthis.meshy.service.file;

import java.util.Collection;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.Map;

import com.addthis.basis.util.Bytes;
import com.addthis.basis.util.Parameter;
import com.addthis.basis.util.Strings;

import com.addthis.meshy.ChannelMaster;
import com.addthis.meshy.ChannelState;
import com.addthis.meshy.Meshy;
import com.addthis.meshy.MeshyConstants;
import com.addthis.meshy.SourceHandler;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import static com.google.common.base.Preconditions.checkState;
import io.netty.buffer.ByteBuf;

public class FileSource extends SourceHandler {

    protected static final Logger log = LoggerFactory.getLogger(FileSource.class);
    static final boolean traceComplete = Parameter.boolValue("meshy.finder.debug.complete", false);

    private final LinkedList list = new LinkedList<>();
    protected String[] fileRequest;
    protected FileReferenceFilter filter;

    public FileSource(ChannelMaster master) {
        super(master, FileTarget.class, true);
    }

    public FileSource(ChannelMaster master, String[] files) {
        this(master);
        requestRemoteFiles(files);
    }

    public FileSource(ChannelMaster master, String[] files, String scope) {
        this(master);
        requestFiles(scope, files);
    }

    public FileSource(ChannelMaster master, String[] files, FileReferenceFilter filter) {
        this(master);
        this.filter = filter;
        requestRemoteFiles(files);
    }

    public void requestRemoteFiles(String... matches) {
        requestFiles("local", matches);
    }

    public void requestRemoteFilesWithUpdates(String... matches) {
        requestFiles("localF", matches);
    }

    public void requestLocalFiles(String... matches) {
        start(MeshyConstants.LINK_NAMED);
        requestFilesPostStart("remote", matches);
    }

    public void requestFiles(String scope, String... matches) {
        start();
        requestFilesPostStart(scope, matches);
    }

    private void requestFilesPostStart(String scope, String... matches) {
        checkState(fileRequest == null, "file search request already started");
        this.fileRequest = matches;
        send(Bytes.toBytes(scope));
        log.debug("{} scope={}", this, scope);
        for (String match : matches) {
            log.trace("{} request={}", this, match);
            send(Bytes.toBytes(match));
        }
        sendComplete();
    }

    @Override
    public String toString() {
        return super.toString() + '(' + (fileRequest != null ? Strings.join(fileRequest, ",") : "-") + ')';
    }

    public Collection getFileList() {
        return list;
    }

    public Map getFileMap() {
        HashMap map = new HashMap<>();
        for (FileReference file : getFileList()) {
            map.put(file.name, file);
        }
        return map;
    }

    @Override
    public void receive(ChannelState state, int length, ByteBuf buffer) throws Exception {
        /* sync not required b/c overridden in server-server calls */
        FileReference ref = new FileReference(Meshy.getBytes(length, buffer));
        if (filter == null || filter.accept(ref)) {
            receiveReference(ref);
        }
        log.trace("{} recv={}", this, list.size());
    }

    @Override
    public void receiveComplete(ChannelState state, int completedSession) throws Exception {
        if (traceComplete) {
            log.info("recv.complete [{}] {}", completedSession, Strings.join(fileRequest, ","));
        }
        super.receiveComplete(state, completedSession);
    }

    // override to detect unexpected channel closures
    @Override
    public void channelClosed(ChannelState state) {
    }

    // override in subclasses for async handling
    // call super() if you still want the list populated
    public void receiveReference(FileReference ref) {
        list.add(ref);
    }

    // override in subclasses for async handling
    @Override
    public void receiveComplete() throws Exception {
        log.debug("{} recvComplete", this);
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy