1 package org.argeo.connect.core;
2
3 import java.util.UUID;
4
5 import javax.jcr.Node;
6 import javax.jcr.NodeIterator;
7 import javax.jcr.Property;
8 import javax.jcr.RepositoryException;
9 import javax.jcr.Session;
10 import javax.jcr.nodetype.NodeType;
11 import javax.jcr.query.Query;
12
13 import org.apache.commons.logging.Log;
14 import org.apache.commons.logging.LogFactory;
15 import org.argeo.connect.AppService;
16 import org.argeo.connect.ConnectConstants;
17 import org.argeo.connect.ConnectException;
18 import org.argeo.connect.ConnectNames;
19 import org.argeo.connect.ConnectTypes;
20 import org.argeo.connect.util.ConnectJcrUtils;
21 import org.argeo.connect.util.RemoteJcrUtils;
22 import org.argeo.connect.util.XPathUtils;
23 import org.argeo.eclipse.ui.EclipseUiUtils;
24 import org.argeo.jcr.JcrUtils;
25 import org.argeo.node.NodeUtils;
26
27 public abstract class AbstractAppService implements AppService {
28 private final static Log log = LogFactory.getLog(AbstractAppService.class);
29
30 public Node publishEntity(Node parent, String nodeType, Node srcNode, boolean removeSrcNode)
31 throws RepositoryException {
32 Node createdNode = null;
33 if (isKnownType(nodeType)) {
34 String relPath = getDefaultRelPath(srcNode);
35
36 if (parent == null) {
37 StackTraceElement[] stack = Thread.currentThread().getStackTrace();
38 StringBuilder builder = new StringBuilder();
39 builder.append("Trying to publish a node with no parent, "
40 + "this approach will soon be forbidden. Calling stack:\n");
41 for (StackTraceElement el : stack) {
42 builder.append(el.toString() + "\n");
43 }
44 log.error(builder.toString());
45 parent = srcNode.getSession().getNode("/" + getBaseRelPath(nodeType));
46 }
47
48
49 String parRelPath = ConnectJcrUtils.parentRelPath(relPath);
50
51 Node tmpParent = null;
52 if (EclipseUiUtils.isEmpty(parRelPath))
53 tmpParent = parent;
54 else
55 tmpParent = JcrUtils.mkdirs(parent, parRelPath);
56
57 createdNode = tmpParent.addNode(ConnectJcrUtils.lastRelPathElement(relPath));
58
59 RemoteJcrUtils.copy(srcNode, createdNode, true);
60 createdNode.addMixin(nodeType);
61 JcrUtils.updateLastModified(createdNode);
62 if (removeSrcNode)
63 srcNode.remove();
64 }
65 return createdNode;
66 }
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83 public Node saveEntity(Node entity, boolean publish) {
84 try {
85 Session session = entity.getSession();
86 if (session.hasPendingChanges()) {
87 JcrUtils.updateLastModified(entity);
88 session.save();
89 }
90 if (entity.isNodeType(NodeType.MIX_VERSIONABLE))
91
92 session.getWorkspace().getVersionManager().checkpoint(entity.getPath());
93 return entity;
94 } catch (RepositoryException e) {
95 throw new ConnectException("Cannot save " + entity, e);
96 }
97 }
98
99
100
101
102
103
104
105
106 public String getDisplayName(Node entity) {
107 String defaultDisplayName = ConnectJcrUtils.get(entity, Property.JCR_TITLE);
108 if (defaultDisplayName == null || "".equals(defaultDisplayName.trim()))
109 return ConnectJcrUtils.getName(entity);
110 else
111 return defaultDisplayName;
112 }
113
114
115
116
117
118 public Node getDraftParent(Session session) throws RepositoryException {
119 Node home = NodeUtils.getUserHome(session);
120 String draftRelPath = ConnectConstants.HOME_APP_SYS_RELPARPATH + "/" + getAppBaseName();
121 return JcrUtils.mkdirs(home, draftRelPath);
122 }
123
124
125
126
127
128
129 public Node createDraftEntity(Session session, String mainMixin) throws RepositoryException {
130 Node parent = getDraftParent(session);
131 String connectUid = UUID.randomUUID().toString();
132 Node draftNode = parent.addNode(connectUid);
133 draftNode.addMixin(mainMixin);
134 draftNode.setProperty(ConnectNames.CONNECT_UID, connectUid);
135 return draftNode;
136 }
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152 public Node getEntityByUid(Session session, String parentPath, String uid) {
153 if (uid == null || "".equals(uid.trim()))
154 throw new ConnectException("uid cannot be null or empty");
155 try {
156 StringBuilder builder = new StringBuilder();
157 builder.append(XPathUtils.descendantFrom(parentPath));
158 builder.append("//element(*, ").append(ConnectTypes.CONNECT_ENTITY).append(")");
159 builder.append("[").append(XPathUtils.getPropertyEquals(ConnectNames.CONNECT_UID, uid)).append("]");
160 Query xpathQuery = XPathUtils.createQuery(session, builder.toString());
161 NodeIterator ni = xpathQuery.execute().getNodes();
162 long niSize = ni.getSize();
163 if (niSize == 0)
164 return null;
165 else if (niSize > 1) {
166
167
168 log.error("Found " + niSize + " entities with connect:uid [" + uid + "] - calling stack:\n "
169 + Thread.currentThread().getStackTrace().toString());
170 Node first = ni.nextNode();
171 throw new ConnectException(
172 "Found " + niSize + " entities for People UID [" + uid + "], First occurence info:\npath: "
173 + first.getPath() + ", node type: " + first.getPrimaryNodeType().getName() + "");
174 } else
175 return ni.nextNode();
176 } catch (RepositoryException e) {
177 throw new ConnectException("Unable to retrieve entity with connect:uid [" + uid + "]", e);
178 }
179 }
180
181 }