package com.framsticks.dumping; import static com.framsticks.core.TreeOperations.*; import com.framsticks.core.Node; import com.framsticks.core.Path; import com.framsticks.params.Access; import com.framsticks.params.CompositeParam; import com.framsticks.params.FramsClass; import com.framsticks.params.ListAccess; import com.framsticks.params.SinkInterface; import com.framsticks.parsers.Savers; import com.framsticks.core.Tree; import com.framsticks.util.*; import com.framsticks.util.dispatching.Dispatching; import com.framsticks.util.dispatching.Future; import org.apache.logging.log4j.Logger; import org.apache.logging.log4j.LogManager; import com.framsticks.util.dispatching.RunAt; import java.util.HashSet; import java.util.Set; import static com.framsticks.util.lang.Containers.filterInstanceof; /** * @author Piotr Sniegowski */ public class SaveStream extends Stream { private final static Logger log = LogManager.getLogger(SaveStream.class.getName()); protected final SinkInterface sink; protected final Tree tree; protected final Future future; protected final Stopwatch stopwatch = new Stopwatch(); protected final Set storedInfo = new HashSet(); private int dispatched = 0; public SaveStream(SinkInterface sink, Tree tree, Path root, Future future) { assert Dispatching.isThreadSafe(); this.sink = sink; this.tree = tree; this.future = future; dispatchWrite(root); } protected void dispatchWrite(final Path path) { ++dispatched; tree.dispatch(new RunAt(tree) { @Override protected void runAt() { write(path); } }); } protected void finished() { assert tree.isActive(); log.info("stored in {}", stopwatch); future.pass(null); } public void write(final Path path) { assert tree.isActive(); if (!path.isResolved()) { log.debug("path {} is not resolved - skipping", path); } else { Access access = bindAccess(path); assert access != null; FramsClass framsClass = access.getFramsClass(); assert framsClass != null; if (!storedInfo.contains(framsClass)) { storedInfo.add(framsClass); sink.print("info ").print(path.getTextual()).breakLine(); sink.print("file").breakLine(); Savers.saveFramsClass(sink, framsClass); sink.print("eof").breakLine(); sink.print("ok").breakLine(); } if (!(access instanceof ListAccess)) { sink.print("get ").print(path.getTextual()).breakLine(); sink.print("file").breakLine(); //stream.print("#" + access.getSelected().getClass().getCanonicalName() + "\n"); access.save(sink); sink.print("eof").breakLine(); sink.print("ok").breakLine(); } for (CompositeParam p : filterInstanceof(access.getParams(), CompositeParam.class)) { final Path childPath = path.appendNode(new Node(path.getTree(), p, access.get(p, Object.class))); if (childPath.isResolved() && getInfoFromCache(childPath) != null) { dispatchWrite(childPath); } } } --dispatched; if (dispatched == 0) { finished(); } } }