View Javadoc
1   package org.argeo.people.ui;
2   
3   import static org.argeo.eclipse.ui.EclipseUiUtils.isEmpty;
4   
5   import java.util.ArrayList;
6   import java.util.List;
7   
8   import javax.jcr.Node;
9   import javax.jcr.NodeIterator;
10  import javax.jcr.Property;
11  import javax.jcr.PropertyIterator;
12  import javax.jcr.RepositoryException;
13  import javax.jcr.Session;
14  import javax.jcr.Value;
15  import javax.jcr.nodetype.NodeType;
16  import javax.jcr.query.Query;
17  import javax.jcr.query.QueryResult;
18  
19  import org.apache.commons.logging.Log;
20  import org.apache.commons.logging.LogFactory;
21  import org.argeo.connect.ConnectNames;
22  import org.argeo.connect.util.ConnectJcrUtils;
23  import org.argeo.connect.util.XPathUtils;
24  import org.argeo.eclipse.ui.EclipseUiUtils;
25  import org.argeo.jcr.JcrUtils;
26  import org.argeo.people.PeopleConstants;
27  import org.argeo.people.PeopleException;
28  import org.argeo.people.PeopleNames;
29  
30  public class PeopleUiUtils {
31  	private final static Log log = LogFactory.getLog(PeopleUiUtils.class);
32  
33  	/* INTERNATIONALISATION HELPERS */
34  
35  	/**
36  	 * Concisely gets the node for the translation of some main properties of
37  	 * the current node given a language by default such a name is at
38  	 * {@link PeopleNames#PEOPLE_ALT_LANGS}/lang
39  	 */
40  	public static Node getAltLangNode(Node currentNode, String lang) {
41  		return getAltLangNode(currentNode, PeopleNames.PEOPLE_ALT_LANGS, lang);
42  	}
43  
44  	/**
45  	 * Concisely gets the node for the translation of some main properties of
46  	 * the current node given a language and the name of an intermediary node
47  	 * 
48  	 * If no rel path is given, we use the default
49  	 * {@link PeopleNames#PEOPLE_ALT_LANGS}
50  	 */
51  	public static Node getAltLangNode(Node currentNode, String relPath, String lang) {
52  		try {
53  			if (EclipseUiUtils.isEmpty(relPath))
54  				relPath = PeopleNames.PEOPLE_ALT_LANGS;
55  			if (!currentNode.hasNode(relPath + "/" + lang))
56  				return null;
57  			else {
58  				return currentNode.getNode(relPath + "/" + lang);
59  			}
60  		} catch (RepositoryException e) {
61  			throw new PeopleException("Cannot get alt property for " + lang, e);
62  		}
63  	}
64  
65  	public static Node getOrCreateAltLanguageNode(Node node, String lang, List<String> mixins) {
66  		return getOrCreateAltLanguageNode(node, PeopleNames.PEOPLE_ALT_LANGS, lang, mixins);
67  	}
68  
69  	public static Node getOrCreateAltLanguageNode(Node node, String relPath, String lang, List<String> mixins) {
70  		try {
71  			Node child = JcrUtils.mkdirs(node, relPath + "/" + lang, NodeType.NT_UNSTRUCTURED);
72  			child.addMixin(NodeType.MIX_LANGUAGE);
73  			if (mixins != null && !mixins.isEmpty())
74  				for (String mixin : mixins)
75  					child.addMixin(mixin);
76  
77  			child.setProperty(Property.JCR_LANGUAGE, lang);
78  			return child;
79  		} catch (RepositoryException e) {
80  			throw new PeopleException("Cannot create child for language " + lang, e);
81  		}
82  	}
83  
84  	/* IMPORT HELPERS */
85  	/**
86  	 * Transforms String property that use the people UID to reference other
87  	 * entities during import to JCR References. Manage both single and multi
88  	 * value prop It retrieves and process all properties that have a _puid
89  	 * suffix
90  	 */
91  	public static void translatePuidToRef(Node node, String nodeType, String basePath, boolean updateChildren) {
92  		try {
93  			Session session = node.getSession();
94  			PropertyIterator pit = node.getProperties();
95  			while (pit.hasNext()) {
96  				Property currProp = pit.nextProperty();
97  				String currName = currProp.getName();
98  				if (currName.endsWith(PeopleConstants.IMPORT_REF_SUFFIX)) {
99  					String newName = currName.substring(0,
100 							currName.length() - PeopleConstants.IMPORT_REF_SUFFIX.length());
101 					if (currProp.isMultiple()) {
102 						Value[] values = currProp.getValues();
103 						List<Node> nodes = new ArrayList<Node>();
104 						for (Value val : values) {
105 							String currId = val.getString();
106 							Node referenced = getEntityByUid(session, currId, nodeType, basePath);
107 							if (referenced == null)
108 								log.warn("Unable to find referenced node with ID " + currId + " for " + currProp);
109 							else
110 								nodes.add(referenced);
111 						}
112 						ConnectJcrUtils.setMultipleReferences(node, newName, nodes);
113 						currProp.remove();
114 					} else {
115 						String currId = currProp.getString();
116 						Node referenced = getEntityByUid(session, currId, nodeType, basePath);
117 						node.setProperty(newName, referenced);
118 						currProp.remove();
119 					}
120 				}
121 			}
122 			if (updateChildren) {
123 				NodeIterator nit = node.getNodes();
124 				while (nit.hasNext()) {
125 					Node currChild = nit.nextNode();
126 					translatePuidToRef(currChild, nodeType, basePath, updateChildren);
127 				}
128 			}
129 		} catch (RepositoryException re) {
130 			throw new PeopleException("Unable to perform post import " + "translation on Node " + node, re);
131 		}
132 	}
133 
134 	public static Node getEntityByUid(Session session, String uid, String nodeType, String basePath) {
135 		if (isEmpty(uid))
136 			throw new PeopleException("Cannot get entity by id by providing an empty people:uid");
137 		try {
138 			String xpathQueryStr = XPathUtils.descendantFrom(basePath) + "//element(*, " + nodeType + ")";
139 			String attrQuery = XPathUtils.getPropertyEquals(ConnectNames.CONNECT_UID, uid);
140 			if (EclipseUiUtils.notEmpty(attrQuery))
141 				xpathQueryStr += "[" + attrQuery + "]";
142 			Query xpathQuery = XPathUtils.createQuery(session, xpathQueryStr);
143 			QueryResult result = xpathQuery.execute();
144 			NodeIterator ni = result.getNodes();
145 
146 			if (ni.getSize() == 0)
147 				return null;
148 			else if (ni.getSize() > 1) {
149 				Node first = ni.nextNode();
150 				throw new PeopleException("Found " + ni.getSize() + " entities for People UID [" + uid
151 						+ "]\n Info on first occurence: " + "\n Path: " + first.getPath() + "\n Node type: "
152 						+ first.getPrimaryNodeType().getName());
153 			} else
154 				return ni.nextNode();
155 		} catch (RepositoryException e) {
156 			throw new PeopleException("Unable to retrieve entity of uid: " + uid + " under " + basePath, e);
157 		}
158 	}
159 }