package org.onehippo.forge.konakart.cms.replication.utils; import org.hippoecm.repository.api.*; import org.hippoecm.repository.standardworkflow.DefaultWorkflow; import org.hippoecm.repository.standardworkflow.FolderWorkflow; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import javax.jcr.*; import java.rmi.RemoteException; import java.util.UUID; public class NodeImagesHelper { public static final String PUBLISHED_STATE = "published"; public static final String UNPUBLISHED_STATE = "unpublished"; public static final Logger log = LoggerFactory.getLogger(NodeImagesHelper.class); /** * Hippo Repository specific predefined folder node type name */ protected String folderNodeTypeName = "image gallery"; /** * The workflow category name to get a folder workflow. We use threepane as this is the same as the CMS uses */ protected String folderNodeWorkflowCategory = "threepane"; /** * The workflow category name to add a new document. */ protected String documentAdditionWorkflowCategory = "new-image-folder"; /** * The workflow category name to add a new folder. */ protected String galleryType = "hippogallery:imageset"; /** * The workflow category name to localize the new document */ protected String defaultWorkflowCategory = "core"; protected Session session; public NodeImagesHelper(Session session) { this.session = session; } public Node createMissingFolders(String absPath) throws Exception { String[] folderNames = absPath.split("/"); Node rootNode = session.getRootNode(); Node curNode = rootNode; String folderNodePath; for (String folderName : folderNames) { String folderNodeName = Codecs.encodeNode(folderName); if (!"".equals(folderNodeName)) { if (curNode.equals(rootNode)) { folderNodePath = "/" + folderNodeName; } else { folderNodePath = curNode.getPath() + "/" + folderNodeName; } if (!session.itemExists(folderNodePath)) { curNode = session.getNode(createNodeByWorkflow(curNode, folderNodeTypeName, folderName)); if (!curNode.hasProperty("hippostd:gallerytype")) { curNode.setProperty("hippostd:gallerytype", galleryType); } } else { curNode = curNode.getNode(folderNodeName); } if (curNode.isNodeType(HippoNodeType.NT_FACETSELECT) || curNode.isNodeType(HippoNodeType.NT_MIRROR)) { String docbaseUuid = curNode.getProperty("hippo:docbase").getString(); // check whether docbaseUuid is a valid uuid, otherwise a runtime IllegalArgumentException is thrown try { UUID.fromString(docbaseUuid); } catch (IllegalArgumentException e) { throw new Exception("hippo:docbase in mirror does not contain a valid uuid", e); } // this is always the canonical curNode = session.getNodeByIdentifier(docbaseUuid); } else { curNode = getCanonicalNode(curNode); } } } return curNode; } @SuppressWarnings("rawtypes") protected String createNodeByWorkflow(Node folderNode, String nodeTypeName, String name) throws Exception { try { folderNode = getCanonicalNode(folderNode); Workflow wf = getWorkflow(folderNodeWorkflowCategory, folderNode); if (wf instanceof FolderWorkflow) { FolderWorkflow fwf = (FolderWorkflow) wf; String category = documentAdditionWorkflowCategory; String nodeName = Codecs.encodeNode(name); String added = fwf.add(category, nodeTypeName, nodeName); if (added == null) { throw new Exception("Failed to add document/folder for type '" + nodeTypeName + "'. Make sure there is a prototype."); } Item addedDocumentVariant = folderNode.getSession().getItem(added); if (addedDocumentVariant instanceof Node && !nodeName.equals(name)) { DefaultWorkflow defaultWorkflow = (DefaultWorkflow) getWorkflow(defaultWorkflowCategory, (Node) addedDocumentVariant); defaultWorkflow.localizeName(name); } return added; } else { throw new Exception("Can't add folder " + name + " [" + nodeTypeName + "] in the folder " + folderNode.getPath() + ", because there is no FolderWorkflow possible on the folder node: " + wf); } } catch (RepositoryException e) { throw new Exception(e); } catch (RemoteException e) { throw new Exception(e); } catch (WorkflowException e) { throw new Exception(e); } } public Node createGalleryItem(Node parentNode, String imageNodeTypeName, String filename) throws RepositoryException { String nodeName = Codecs.encodeNode(filename); if (parentNode.hasNode(nodeName)) { Node handleNode = parentNode.getNode(nodeName); if (handleNode.hasNode(nodeName)) { return handleNode.getNode(nodeName); } return null; } // Create the handle Node handle = parentNode.addNode(filename, "hippo:handle"); handle.addMixin("hippo:hardhandle"); handle.addMixin("hippo:translated"); // Create the image folder Node childNode = handle.addNode(filename, imageNodeTypeName); // Add mixin childNode.addMixin("hippo:harddocument"); // Add extra definitions childNode.setProperty("hippo:availability", new String[]{"live", "preview"}); childNode.setProperty("hippogallery:filename", filename); return childNode; } /** * Invokes {@link javax.jcr.Session#refresh(boolean)}. * * @param keepChanges . * @throws Exception . */ public void refresh(boolean keepChanges) throws Exception { try { session.refresh(keepChanges); } catch (Exception e) { throw new Exception(e); } } public Workflow getWorkflow(String category, Node node) throws RepositoryException { Workspace workspace = session.getWorkspace(); ClassLoader workspaceClassloader = workspace.getClass().getClassLoader(); ClassLoader currentClassloader = Thread.currentThread().getContextClassLoader(); try { if (workspaceClassloader.equals(currentClassloader)) { Thread.currentThread().setContextClassLoader(workspaceClassloader); } WorkflowManager wfm = ((HippoWorkspace) workspace).getWorkflowManager(); return wfm.getWorkflow(category, node); } catch (RepositoryException e) { throw e; } catch (Exception e) { // other exception which are not handled properly in the repository (we cannot do better here then just log them) if (log.isDebugEnabled()) { log.warn("Exception in workflow", e); } else { log.warn("Exception in workflow: {}", e.toString()); } } finally { if (workspaceClassloader.equals(currentClassloader)) { Thread.currentThread().setContextClassLoader(currentClassloader); } } return null; } private Node getCanonicalNode(Node folderNode) { if (folderNode instanceof HippoNode) { HippoNode hnode = (HippoNode) folderNode; try { Node canonical = hnode.getCanonicalNode(); if (canonical == null) { log.debug("Cannot get canonical node for '{}'. This means there is no phyiscal equivalence of the " + "virtual node. Return null", folderNode.getPath()); } return canonical; } catch (RepositoryException e) { throw new RuntimeException(e); } } return folderNode; } }