package com.thinkbiganalytics.metadata.modeshape.support; /*- * #%L * thinkbig-metadata-modeshape * %% * Copyright (C) 2017 ThinkBig Analytics * %% * 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. * #L% */ import com.google.common.base.Predicate; import com.google.common.collect.Iterables; import com.thinkbiganalytics.metadata.modeshape.MetadataRepositoryException; import com.thinkbiganalytics.metadata.modeshape.common.JcrObject; import java.util.ArrayList; import java.util.List; import javax.jcr.Node; import javax.jcr.NodeIterator; import javax.jcr.RepositoryException; import javax.jcr.Session; import javax.jcr.lock.LockManager; import javax.jcr.nodetype.NodeType; import javax.jcr.version.Version; import javax.jcr.version.VersionHistory; import javax.jcr.version.VersionIterator; import javax.jcr.version.VersionManager; /** */ public class JcrVersionUtil { /** * Returns the LockManager object from the given session. * * @param session {@link Session} * @return a {@link LockManager} object */ public static LockManager getLockManager(Session session) throws RepositoryException { LockManager lockMgr = session.getWorkspace().getLockManager(); return lockMgr; } /** * Returns the VersionManager object from the given session. * * @param session {@link Session} * @return a {@link VersionManager} object */ public static VersionManager getVersionManager(Session session) throws RepositoryException { VersionManager versionMgr = session.getWorkspace().getVersionManager(); return versionMgr; } /** * Sets the given node to checked-out status. * * @param node node to check-out */ public static void checkout(Node node) throws RepositoryException { //getVersionManager(node.getSession()).checkout(node.getPath()); } /** * Creates for the given node a new version and returns that version. Put the node into the checked-in state. * * @param node node to checkin * @return the created version */ public static Version checkin(Node node) throws RepositoryException { if (node.getSession().isLive()) { //return getVersionManager(node.getSession()).checkin(node.getPath()); return null; } else { return null; } } public static void checkinRecursively(Node node) { try { NodeIterator it = node.getNodes(); while (it.hasNext()) { checkinRecursively(it.nextNode()); } if (node.isCheckedOut() && node.isNodeType(NodeType.MIX_VERSIONABLE)) { //node.checkin(); checkin(node); } } catch (RepositoryException e) { throw new MetadataRepositoryException("Could not perform check-in", e); } } public static void checkoutRecursively(Node node) { try { NodeIterator it = node.getNodes(); while (it.hasNext()) { checkoutRecursively(it.nextNode()); } if (!node.isCheckedOut() && node.isNodeType(NodeType.MIX_VERSIONABLE)) { //node.checkout(); checkout(node); } } catch (RepositoryException e) { throw new MetadataRepositoryException("Could not perform check-out", e); } } /** * Places a lock on the given node. * * @param node the node to be locked * @param isDeep if <code>true</code> this lock will apply to this node and all its descendants; if <code>false</code>, it applies only to this node. * @param isSessionScoped if <code>true</code>, this lock expires with the current session; if <code>false</code> it expires when explicitly or automatically unlocked for some other reason. * @param timeoutHint desired lock timeout in seconds (servers are free to ignore this value); specify Long.MAX_VALUE for no timeout. * @param ownerInfo a string containing owner information supplied by the client; servers are free to ignore this value. * @see javax.jcr.lock.LockManager#lock(String, boolean, boolean, long, String) */ public static void lock(Node node, boolean isDeep, boolean isSessionScoped, long timeoutHint, String ownerInfo) { try { getLockManager(node.getSession()).lock(node.getPath(), isDeep, isSessionScoped, timeoutHint, ownerInfo); } catch (RepositoryException e) { throw new MetadataRepositoryException("Could not perform lock", e); } } /** * Removes the lock on the given node. * * @param node the node unlock * @see javax.jcr.lock.LockManager#unlock(String) */ public static void unlock(Node node) { try { getLockManager(node.getSession()).unlock(node.getPath()); } catch (RepositoryException e) { throw new MetadataRepositoryException("Could not perform unlock", e); } } public static Version getBaseVersion(Node node) { String nodeName = null; if (!JcrUtil.isVersionable(node)) { return null; } try { nodeName = node.getName(); return JcrVersionUtil.getVersionManager(node.getSession()).getBaseVersion(node.getPath()); } catch (RepositoryException e) { throw new MetadataRepositoryException("Unable to find Base Version for " + nodeName, e); } } public static List<Version> getVersions(Node node) { String nodeName = null; if (!JcrUtil.isVersionable(node)) { return null; } try { nodeName = node.getName(); List<Version> versions = new ArrayList<>(); VersionHistory history = JcrVersionUtil.getVersionManager(node.getSession()).getVersionHistory(node.getPath()); VersionIterator itr = history.getAllVersions(); String id = history.getVersionableIdentifier(); while (itr.hasNext()) { Version version = itr.nextVersion(); versions.add(version); } return versions; } catch (RepositoryException e) { throw new MetadataRepositoryException("Unable to find Version History for " + nodeName, e); } } public static <T extends JcrObject> T getVersionedNode(Version version, Class<T> type, Object[] constructorArgs) { String nodeName = null; String versionName = null; try { versionName = version.getName(); Node node = version.getFrozenNode(); nodeName = node.getName(); String entityId = version.getContainingHistory().getVersionableIdentifier(); T obj = JcrUtil.constructNodeObject(node, type, constructorArgs); obj.setVersionName(versionName); obj.setVersionableIdentifier(entityId); return obj; } catch (RepositoryException e) { throw new MetadataRepositoryException("Unable to find Version " + versionName + " for Node " + nodeName, e); } } public static Version findVersion(Node node, final String versionName) { if (!JcrUtil.isVersionable(node)) { return null; } Version version = Iterables.tryFind(getVersions(node), new Predicate<Version>() { @Override public boolean apply(Version version) { try { String identifier = node.getIdentifier(); String frozenIdentifer = JcrPropertyUtil.getString(version.getFrozenNode(), "jcr:frozenUuid"); return version.getName().equalsIgnoreCase(versionName) && frozenIdentifer.equalsIgnoreCase(identifier); } catch (RepositoryException e) { } return false; } }).orNull(); return version; } public static <T extends JcrObject> T getVersionedNode(Version version, Class<T> type) { return getVersionedNode(version, type, null); } public static <T extends JcrObject> T getVersionedNode(JcrObject node, String versionNumber, Class<T> type) { Version version = findVersion(node.getNode(), versionNumber); if (version != null) { return getVersionedNode(version, type); } throw new MetadataRepositoryException("Unable to find Version " + versionNumber + " for Node " + node.getNodeName()); } }