View Javadoc
1   /**
2    * This file Copyright (c) 2013-2016 Magnolia International
3    * Ltd.  (http://www.magnolia-cms.com). All rights reserved.
4    *
5    *
6    * This file is dual-licensed under both the Magnolia
7    * Network Agreement and the GNU General Public License.
8    * You may elect to use one or the other of these licenses.
9    *
10   * This file is distributed in the hope that it will be
11   * useful, but AS-IS and WITHOUT ANY WARRANTY; without even the
12   * implied warranty of MERCHANTABILITY or FITNESS FOR A
13   * PARTICULAR PURPOSE, TITLE, or NONINFRINGEMENT.
14   * Redistribution, except as permitted by whichever of the GPL
15   * or MNA you select, is prohibited.
16   *
17   * 1. For the GPL license (GPL), you can redistribute and/or
18   * modify this file under the terms of the GNU General
19   * Public License, Version 3, as published by the Free Software
20   * Foundation.  You should have received a copy of the GNU
21   * General Public License, Version 3 along with this program;
22   * if not, write to the Free Software Foundation, Inc., 51
23   * Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
24   *
25   * 2. For the Magnolia Network Agreement (MNA), this file
26   * and the accompanying materials are made available under the
27   * terms of the MNA which accompanies this distribution, and
28   * is available at http://www.magnolia-cms.com/mna.html
29   *
30   * Any modifications to this file must keep this entire header
31   * intact.
32   *
33   */
34  package info.magnolia.ui.vaadin.integration.jcr;
35  
36  import info.magnolia.cms.core.version.VersionManager;
37  import info.magnolia.cms.core.version.VersionedNode;
38  import info.magnolia.cms.core.version.VersionedNodeChild;
39  import info.magnolia.context.MgnlContext;
40  import info.magnolia.objectfactory.Components;
41  
42  import java.util.ArrayList;
43  import java.util.List;
44  
45  import javax.jcr.Item;
46  import javax.jcr.ItemNotFoundException;
47  import javax.jcr.Node;
48  import javax.jcr.RepositoryException;
49  import javax.jcr.Session;
50  
51  import org.apache.commons.lang3.StringUtils;
52  import org.slf4j.Logger;
53  import org.slf4j.LoggerFactory;
54  
55  /**
56   * Utility methods for item ids used in the container.
57   * <p/>
58   * The format is:
59   * <ul>
60   *     <li>for nodes &lt;node identifier&gt;
61   *     <li>for properties &lt;node identifier&gt;@&lt;propertyName&gt;
62   * </ul>
63   */
64  public class JcrItemUtil {
65  
66      private static final Logger log = LoggerFactory.getLogger(JcrItemUtil.class);
67  
68      /**
69       * String separating property name and node identifier.
70       */
71      public static final String PROPERTY_NAME_AND_IDENTIFIER_SEPARATOR = "@";
72  
73      /**
74       * @return all chars in front of #PROPERTY_NAME_AND_IDENTIFIER_SEPARATOR - if it doesn't contain #PROPERTY_NAME_AND_IDENTIFIER_SEPARATOR the provided itemId (then we assume it's already a nodeId)
75       */
76      public static String parseNodeIdentifier(final String itemId) {
77          return isPropertyItemId(itemId) ? itemId.substring(0, itemId.indexOf(PROPERTY_NAME_AND_IDENTIFIER_SEPARATOR)) : itemId;
78      }
79  
80      public static String parsePropertyName(final String itemId) {
81          return itemId.substring(itemId.indexOf(PROPERTY_NAME_AND_IDENTIFIER_SEPARATOR) + 1);
82      }
83  
84      public static boolean isPropertyItemId(final String itemId) {
85          return itemId != null && itemId.contains(PROPERTY_NAME_AND_IDENTIFIER_SEPARATOR);
86      }
87  
88      /**
89       * Returns the JCR Item represented by the given itemId or returns null if it doesn't exist.
90       */
91      public static Item getJcrItem(final JcrItemId itemId) throws RepositoryException {
92          if (itemId == null) {
93              return null;
94          }
95          Node node;
96          String workspaceName = itemId.getWorkspace();
97          try {
98              node = MgnlContext.getJCRSession(workspaceName).getNodeByIdentifier(itemId.getUuid());
99              if (itemId instanceof VersionedChildJcrItemId) {
100                 Node parent = Components.getComponent(VersionManager.class).getVersion(node, ((VersionedChildJcrItemId) itemId).getParent().getVersionName());
101                 node = parent.getNode(((VersionedChildJcrItemId) itemId).getRelPath());
102             } else if (itemId instanceof VersionedJcrItemId) {
103                 node = Components.getComponent(VersionManager.class).getVersion(node, ((VersionedJcrItemId) itemId).getVersionName());
104             }
105         } catch (ItemNotFoundException e) {
106             log.debug("Couldn't find item with id {} in workspace {}.", itemId, workspaceName);
107             return null;
108         }
109 
110         if (!(itemId instanceof JcrPropertyItemId)) {
111             return node;
112         }
113 
114         final String propertyName = ((JcrPropertyItemId) itemId).getPropertyName();
115         if (node.hasProperty(propertyName)) {
116             return node.getProperty(propertyName);
117         }
118         return null;
119     }
120 
121     public static boolean itemExists(JcrItemId itemId) throws RepositoryException {
122         return getJcrItem(itemId) != null;
123     }
124 
125     /**
126      * Returns the ItemId for given JCR Item or return null if given null.
127      *
128      * returns JcrItemId for Node
129      * returns VersionedJcrItemId for VersionedNode
130      * returns VersionedChildJcrItemId for VersionedNodeChild
131      */
132     public static JcrItemId getItemId(final Item jcrItem) throws RepositoryException {
133         if (jcrItem == null) {
134             return null;
135         }
136 
137         if (jcrItem.isNode()) {
138             String identifier = ((Node) jcrItem).getIdentifier();
139             String workspace = jcrItem.getSession().getWorkspace().getName();
140             if (jcrItem instanceof VersionedNode) {
141                 identifier = ((VersionedNode) jcrItem).getBaseNode().getIdentifier();
142                 workspace = jcrItem.getSession().getWorkspace().getName();
143                 return new VersionedJcrItemId(identifier, workspace, ((VersionedNode) jcrItem).unwrap().getName());
144             } else if (jcrItem instanceof VersionedNodeChild) {
145                 Node parent = jcrItem.getParent();
146                 String relpath = jcrItem.getName();
147 
148                 while (parent instanceof VersionedNodeChild) {
149                     relpath = parent.getName() + "/" + relpath;
150                     parent = parent.getParent();
151                 }
152 
153                 identifier = ((VersionedNode) parent).getBaseNode().getIdentifier();
154                 workspace = parent.getSession().getWorkspace().getName();
155                 VersionedJcrItemId parentItemId = new VersionedJcrItemId(identifier, workspace, ((VersionedNode) parent).unwrap().getName());
156 
157                 return new VersionedChildJcrItemId(parentItemId, relpath);
158             }
159 
160             return new JcrNodeItemId(identifier, workspace);
161         } else {
162             return new JcrPropertyItemId((jcrItem.getParent()).getIdentifier(), jcrItem.getSession().getWorkspace().getName(), jcrItem.getName());
163         }
164     }
165 
166     /**
167      * Returns the itemId for a node at the given path if it exists, otherwise returns null.
168      */
169     public static JcrItemId getItemId(final String workspaceName, final String absPath) throws RepositoryException {
170 
171         if (StringUtils.isEmpty(workspaceName) || StringUtils.isEmpty(absPath)) {
172             return null;
173         }
174 
175         Session session = MgnlContext.getJCRSession(workspaceName);
176         if (!session.nodeExists(absPath)) {
177             return null;
178         }
179 
180         return getItemId(session.getNode(absPath));
181     }
182 
183     public static List<Item> getJcrItems(List<JcrItemId> ids) {
184         // sanity check
185         List<Item> items = new ArrayList<Item>();
186         for (JcrItemId id : ids) {
187             Item item;
188             try {
189                 item = getJcrItem(id);
190                 if (item != null) {
191                     items.add(item);
192                 }
193             } catch (RepositoryException e) {
194                 log.debug("Cannot find item with id [{}] in workspace [{}].", id.getUuid(), id.getWorkspace());
195             } catch (IllegalArgumentException e1) {
196                 log.debug("Workspace [{}] is not initialized.", id.getWorkspace());
197             }
198         }
199         return items;
200     }
201 
202     public static String getItemPath(Item item) {
203         if (item == null) {
204             return null;
205         }
206         String path = "unknown";
207         try {
208             if (item.isNode()) {
209                 path = item.getPath();
210             } else {
211                 String parentPath = item.getParent().getPath();
212                 String name = item.getName();
213                 path = parentPath + PROPERTY_NAME_AND_IDENTIFIER_SEPARATOR + name;
214             }
215         } catch (RepositoryException re) {
216             log.error("Cannot get path for item: " + item);
217         }
218         return path;
219     }
220 
221 }