@Override
public void updateDocument( DocumentChanges documentChanges ) {
String id = documentChanges.getDocumentId();
Document document = documentChanges.getDocument();
DocumentReader reader = readDocument(document);
File file = fileFor(id);
String idOrig = id;
// if we're dealing with the root of the connector, we can't process any moves/removes because that would go "outside" the
// connector scope
if (!isRoot(id)) {
String newParentId = reader.getParentIds().get(0);
File parent = file.getParentFile();
String oldParentId = idFor(parent);
if (!oldParentId.equals(newParentId)) {
// The node has a new parent (via the 'update' method), meaning it was moved ...
File newParent = fileFor(newParentId);
File newFile = new File(newParent, file.getName());
if (!newParent.exists()) {
parent.mkdirs(); // in case they were removed since we created them ...
}
if (!newParent.canWrite()) {
String parentPath = newParent.getAbsolutePath();
String msg = JcrI18n.fileConnectorCannotWriteToDirectory.text(getSourceName(), getClass(), parentPath);
throw new DocumentStoreException(id, msg);
}
if (!file.renameTo(newFile)) {
getLogger().debug("Cannot move {0} to {1}", file.getAbsolutePath(), newFile.getAbsolutePath());
} else {
id = idFor(newFile);
// Make sure any existing extra properties are also kept up-to-date
// Note that if the children ar folders, we don't need to walk them recursively because the node id will
// reflect the new folder structure of the rename
moveExtraProperties(idOrig, id);
}
} else {
// It is the same parent as before ...
if (!parent.exists()) {
parent.mkdirs(); // in case they were removed since we created them ...
}
if (!parent.canWrite()) {
String parentPath = parent.getAbsolutePath();
String msg = JcrI18n.fileConnectorCannotWriteToDirectory.text(getSourceName(), getClass(), parentPath);
throw new DocumentStoreException(id, msg);
}
}
}
// children renames have to be processed in the parent
DocumentChanges.ChildrenChanges childrenChanges = documentChanges.getChildrenChanges();
Map<String, Name> renamedChildren = childrenChanges.getRenamed();
for (String renamedChildId : renamedChildren.keySet()) {
File child = fileFor(renamedChildId);
Name newName = renamedChildren.get(renamedChildId);
String newNameStr = getContext().getValueFactories().getStringFactory().create(newName);
File renamedChild = new File(file, newNameStr);
if (!child.renameTo(renamedChild)) {
getLogger().debug("Cannot rename {0} to {1}", child, renamedChild);
} else {
// Make sure any existing extra properties are also kept up-to-date
// Note that if the children ar folders, we don't need to walk them recursively because the node id will reflect
// the new folder structure of the rename
moveExtraProperties(idFor(child), idFor(renamedChild));
}
}
String primaryType = reader.getPrimaryTypeName();
Map<Name, Property> properties = reader.getProperties();
id = idOrig;
ExtraProperties extraProperties = extraPropertiesFor(id, true);
extraProperties.addAll(properties).except(JCR_PRIMARY_TYPE, JCR_CREATED, JCR_LAST_MODIFIED, JCR_DATA);
try {
if (NT_FILE.equals(primaryType)) {
file.createNewFile();
} else if (NT_FOLDER.equals(primaryType)) {
file.mkdir();
} else if (isContentNode(id)) {
Property content = reader.getProperty(JCR_DATA);
BinaryValue binary = factories().getBinaryFactory().create(content.getFirstValue());
OutputStream ostream = new BufferedOutputStream(new FileOutputStream(file));
IoUtil.write(binary.getStream(), ostream);
if (!NT_RESOURCE.equals(primaryType)) {
// This is the "jcr:content" child, but the primary type is non-standard so record it as an extra property