JcrExporter.java 6.55 KB
/*
 * Decompiled with CFR 0_118.
 * 
 * Could not load the following classes:
 *  javax.jcr.Binary
 *  javax.jcr.Node
 *  javax.jcr.NodeIterator
 *  javax.jcr.Property
 *  javax.jcr.RepositoryException
 *  javax.jcr.Session
 *  javax.jcr.ValueFactory
 */
package com.day.jcr.vault.fs.io;

import com.day.jcr.vault.fs.api.AccessType;
import com.day.jcr.vault.fs.api.Artifact;
import com.day.jcr.vault.fs.api.VaultFile;
import com.day.jcr.vault.fs.io.AbstractExporter;
import com.day.jcr.vault.fs.io.ExportInfo;
import com.day.jcr.vault.util.PathUtil;
import com.day.jcr.vault.util.Text;
import java.io.IOException;
import java.io.InputStream;
import java.util.Calendar;
import java.util.Collection;
import java.util.Map;
import javax.jcr.Binary;
import javax.jcr.Node;
import javax.jcr.NodeIterator;
import javax.jcr.Property;
import javax.jcr.RepositoryException;
import javax.jcr.Session;
import javax.jcr.ValueFactory;

public class JcrExporter
extends AbstractExporter {
    private final Node localParent;
    private boolean autoDeleteFiles;

    public JcrExporter(Node localFile) {
        this.localParent = localFile;
    }

    public boolean isAutoDeleteFiles() {
        return this.autoDeleteFiles;
    }

    public void setAutoDeleteFiles(boolean autoDeleteFiles) {
        this.autoDeleteFiles = autoDeleteFiles;
    }

    public void open() throws IOException, RepositoryException {
        this.scan(this.localParent);
    }

    public void close() throws IOException, RepositoryException {
        if (this.autoDeleteFiles) {
            for (ExportInfo.Entry e : this.exportInfo.getEntries().values()) {
                if (e.type != ExportInfo.Type.DELETE) continue;
                String relPath = PathUtil.getRelativePath(this.localParent.getPath(), e.path);
                try {
                    Node node = this.localParent.getNode(relPath);
                    node.remove();
                    this.track("D", relPath);
                }
                catch (RepositoryException e1) {
                    this.track((Exception)e1, relPath);
                }
            }
        }
        this.localParent.save();
    }

    private void scan(Node dir) throws RepositoryException {
        NodeIterator iter = dir.getNodes();
        while (iter.hasNext()) {
            Node child = iter.nextNode();
            String name = child.getName();
            if (name.equals(".svn") || name.equals(".vlt")) continue;
            if (child.isNodeType("nt:folder")) {
                this.exportInfo.update(ExportInfo.Type.RMDIR, child.getPath());
                this.scan(child);
                continue;
            }
            if (!child.isNodeType("nt:file")) continue;
            this.exportInfo.update(ExportInfo.Type.DELETE, child.getPath());
        }
    }

    public void createDirectory(VaultFile file, String relPath) throws RepositoryException, IOException {
        this.getOrCreateItem(this.getPlatformFilePath(file, relPath), true);
    }

    public void createDirectory(String relPath) throws IOException {
        this.getOrCreateItem(relPath, true);
    }

    public void writeFile(VaultFile file, String relPath) throws RepositoryException, IOException {
        Node local = this.getOrCreateItem(this.getPlatformFilePath(file, relPath), false);
        this.track(local.isNew() ? "A" : "U", relPath);
        Node content = local.hasNode("jcr:content") ? local.getNode("jcr:content") : local.addNode("jcr:content", "nt:resource");
        Artifact a = file.getArtifact();
        switch (a.getPreferredAccess()) {
            case NONE: {
                throw new RepositoryException("Artifact has no content.");
            }
            case SPOOL: 
            case STREAM: {
                InputStream in = a.getInputStream();
                Binary b = content.getSession().getValueFactory().createBinary(in);
                content.setProperty("jcr:data", b);
                b.dispose();
                in.close();
            }
        }
        Calendar now = Calendar.getInstance();
        if (a.getLastModified() >= 0) {
            now.setTimeInMillis(a.getLastModified());
        }
        content.setProperty("jcr:lastModified", now);
        if (a.getContentType() != null) {
            content.setProperty("jcr:mimeType", a.getContentType());
        } else if (!content.hasProperty("jcr:mimeType")) {
            content.setProperty("jcr:mimeType", "application/octet-stream");
        }
    }

    public void writeFile(InputStream in, String relPath) throws IOException {
        try {
            Node local = this.getOrCreateItem(relPath, false);
            Node content = local.hasNode("jcr:content") ? local.getNode("jcr:content") : local.addNode("jcr:content", "nt:resource");
            Binary b = content.getSession().getValueFactory().createBinary(in);
            content.setProperty("jcr:data", b);
            content.setProperty("jcr:lastModified", Calendar.getInstance());
            if (!content.hasProperty("jcr:mimeType")) {
                content.setProperty("jcr:mimeType", "application/octet-stream");
            }
            b.dispose();
            in.close();
        }
        catch (RepositoryException e) {
            IOException io = new IOException("Error while writing file " + relPath);
            io.initCause((Throwable)e);
            throw io;
        }
    }

    private Node getOrCreateItem(String relPath, boolean isDir) throws IOException {
        try {
            String[] segments = Text.explode(relPath, 47);
            Node root = this.localParent;
            for (int i = 0; i < segments.length; ++i) {
                String s = segments[i];
                if (root.hasNode(s)) {
                    root = root.getNode(s);
                    if (isDir) {
                        this.exportInfo.update(ExportInfo.Type.NOP, root.getPath());
                        continue;
                    }
                    this.exportInfo.update(ExportInfo.Type.UPDATE, root.getPath());
                    continue;
                }
                if (i == segments.length - 1 && !isDir) {
                    root = root.addNode(s, "nt:file");
                    this.exportInfo.update(ExportInfo.Type.ADD, root.getPath());
                    continue;
                }
                root = root.addNode(s, "nt:folder");
                this.exportInfo.update(ExportInfo.Type.MKDIR, root.getPath());
            }
            return root;
        }
        catch (RepositoryException e) {
            IOException io = new IOException("Error while creating item " + relPath);
            io.initCause((Throwable)e);
            throw io;
        }
    }

}