View Javadoc
1   /**
2    * This file Copyright (c) 2013-2018 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  @Deprecated
65  public class JcrItemUtil {
66  
67      private static final Logger log = LoggerFactory.getLogger(JcrItemUtil.class);
68  
69      /**
70       * String separating property name and node identifier.
71       */
72      public static final String PROPERTY_NAME_AND_IDENTIFIER_SEPARATOR = "@";
73  
74      private static final String ESCAPED_PROPERTY_NAME_AND_IDENTIFIER_SEPARATOR = "[commat]";
75  
76      /**
77       * @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)
78       */
79      public static String parseNodeIdentifier(final String itemId) {
80          return isPropertyItemId(itemId) ? unescapeCommercialAt(itemId.substring(0, itemId.indexOf(PROPERTY_NAME_AND_IDENTIFIER_SEPARATOR))) : unescapeCommercialAt(itemId);
81      }
82  
83      public static String parsePropertyName(final String itemId) {
84          return unescapeCommercialAt(itemId.substring(itemId.indexOf(PROPERTY_NAME_AND_IDENTIFIER_SEPARATOR) + 1));
85      }
86  
87      public static boolean isPropertyItemId(final String itemId) {
88          return itemId != null && itemId.contains(PROPERTY_NAME_AND_IDENTIFIER_SEPARATOR);
89      }
90  
91      /**
92       * Returns the JCR Item represented by the given itemId or returns null if it doesn't exist.
93       */
94      public static Item getJcrItem(final JcrItemId itemId) throws RepositoryException {
95          if (itemId == null) {
96              return null;
97          }
98          Node node;
99          String workspaceName = itemId.getWorkspace();
100         try {
101             node = MgnlContext.getJCRSession(workspaceName).getNodeByIdentifier(itemId.getUuid());
102             if (itemId instanceof VersionedChildJcrItemId) {
103                 Node parent = Components.getComponent(VersionManager.class).getVersion(node, ((VersionedChildJcrItemId) itemId).getParent().getVersionName());
104                 node = parent.getNode(((VersionedChildJcrItemId) itemId).getRelPath());
105             } else if (itemId instanceof VersionedJcrItemId) {
106                 node = Components.getComponent(VersionManager.class).getVersion(node, ((VersionedJcrItemId) itemId).getVersionName());
107             }
108         } catch (ItemNotFoundException e) {
109             log.debug("Couldn't find item with id {} in workspace {}.", itemId, workspaceName);
110             return null;
111         }
112 
113         if (!(itemId instanceof JcrPropertyItemId)) {
114             return node;
115         }
116 
117         final String propertyName = ((JcrPropertyItemId) itemId).getPropertyName();
118         if (node.hasProperty(propertyName)) {
119             return node.getProperty(propertyName);
120         }
121         return null;
122     }
123 
124     public static boolean itemExists(JcrItemId itemId) throws RepositoryException {
125         return getJcrItem(itemId) != null;
126     }
127 
128     /**
129      * Returns the ItemId for given JCR Item or return null if given null.
130      *
131      * returns JcrItemId for Node
132      * returns VersionedJcrItemId for VersionedNode
133      * returns VersionedChildJcrItemId for VersionedNodeChild
134      */
135     public static JcrItemId getItemId(final Item jcrItem) throws RepositoryException {
136         if (jcrItem == null) {
137             return null;
138         }
139 
140         if (jcrItem.isNode()) {
141             String identifier = ((Node) jcrItem).getIdentifier();
142             String workspace = jcrItem.getSession().getWorkspace().getName();
143             if (jcrItem instanceof VersionedNode) {
144                 identifier = ((VersionedNode) jcrItem).getBaseNode().getIdentifier();
145                 workspace = jcrItem.getSession().getWorkspace().getName();
146                 return new VersionedJcrItemId(identifier, workspace, ((VersionedNode) jcrItem).unwrap().getName());
147             } else if (jcrItem instanceof VersionedNodeChild) {
148                 Node parent = jcrItem.getParent();
149                 String relpath = jcrItem.getName();
150 
151                 while (parent instanceof VersionedNodeChild) {
152                     relpath = parent.getName() + "/" + relpath;
153                     parent = parent.getParent();
154                 }
155 
156                 identifier = ((VersionedNode) parent).getBaseNode().getIdentifier();
157                 workspace = parent.getSession().getWorkspace().getName();
158                 VersionedJcrItemIdVersionedJcrItemId.html#VersionedJcrItemId">VersionedJcrItemId parentItemId = new VersionedJcrItemId(identifier, workspace, ((VersionedNode) parent).unwrap().getName());
159 
160                 return new VersionedChildJcrItemId(parentItemId, relpath);
161             }
162 
163             return new JcrNodeItemId(identifier, workspace);
164         } else {
165             return new JcrPropertyItemId((jcrItem.getParent()).getIdentifier(), jcrItem.getSession().getWorkspace().getName(), jcrItem.getName());
166         }
167     }
168 
169     /**
170      * Returns the itemId for a node at the given path if it exists, otherwise returns null.
171      */
172     public static JcrItemId getItemId(final String workspaceName, final String absPath) throws RepositoryException {
173 
174         if (StringUtils.isEmpty(workspaceName) || StringUtils.isEmpty(absPath)) {
175             return null;
176         }
177 
178         Session session = MgnlContext.getJCRSession(workspaceName);
179         String unescapedAbsPath = unescapeCommercialAt(absPath);
180         if (!session.nodeExists(unescapedAbsPath)) {
181             return null;
182         }
183 
184         return getItemId(session.getNode(unescapedAbsPath));
185     }
186 
187     public static List<Item> getJcrItems(List<JcrItemId> ids) {
188         // sanity check
189         List<Item> items = new ArrayList<Item>();
190         for (JcrItemId id : ids) {
191             Item item;
192             try {
193                 item = getJcrItem(id);
194                 if (item != null) {
195                     items.add(item);
196                 }
197             } catch (RepositoryException e) {
198                 log.debug("Cannot find item with id [{}] in workspace [{}].", id.getUuid(), id.getWorkspace());
199             } catch (IllegalArgumentException e1) {
200                 log.debug("Workspace [{}] is not initialized.", id.getWorkspace());
201             }
202         }
203         return items;
204     }
205 
206     public static String getItemPath(Item item) {
207         if (item == null) {
208             return null;
209         }
210         String path = "unknown";
211         try {
212             if (item.isNode()) {
213                 path = escapeCommercialAt(item.getPath());
214             } else {
215                 String parentPath = item.getParent().getPath();
216                 String name = item.getName();
217                 path = escapeCommercialAt(parentPath) + PROPERTY_NAME_AND_IDENTIFIER_SEPARATOR + escapeCommercialAt(name);
218             }
219         } catch (RepositoryException re) {
220             log.error("Cannot get path for item: " + item);
221         }
222         return path;
223     }
224 
225     private static String escapeCommercialAt(String toEscape) {
226         return StringUtils.replace(toEscape, PROPERTY_NAME_AND_IDENTIFIER_SEPARATOR, ESCAPED_PROPERTY_NAME_AND_IDENTIFIER_SEPARATOR);
227     }
228 
229     private static String unescapeCommercialAt(String toUnescape) {
230         return StringUtils.replace(toUnescape, ESCAPED_PROPERTY_NAME_AND_IDENTIFIER_SEPARATOR, PROPERTY_NAME_AND_IDENTIFIER_SEPARATOR);
231     }
232 
233 }