View Javadoc
1   package org.argeo.people.core;
2   
3   import static org.argeo.connect.util.ConnectUtils.isEmpty;
4   import static org.argeo.connect.util.ConnectUtils.notEmpty;
5   
6   import javax.jcr.Node;
7   import javax.jcr.Property;
8   import javax.jcr.RepositoryException;
9   import javax.jcr.Session;
10  import javax.jcr.nodetype.NodeType;
11  
12  import org.argeo.connect.ConnectNames;
13  import org.argeo.connect.resources.ResourcesService;
14  import org.argeo.connect.util.ConnectJcrUtils;
15  import org.argeo.jcr.JcrUtils;
16  import org.argeo.people.PeopleException;
17  import org.argeo.people.PeopleNames;
18  import org.argeo.people.PeopleService;
19  import org.argeo.people.PeopleTypes;
20  import org.argeo.people.PersonService;
21  import org.argeo.people.util.PeopleJcrUtils;
22  
23  /** Concrete access to people {@link PersonService} */
24  public class PersonServiceImpl implements PersonService, PeopleNames {
25  
26  	private final PeopleService peopleService;
27  	private final ResourcesService resourceService;
28  
29  	public PersonServiceImpl(PeopleService peopleService, ResourcesService resourceService) {
30  		this.peopleService = peopleService;
31  		this.resourceService = resourceService;
32  	}
33  
34  	@Override
35  	public String getDefaultDisplayName(Node entity) {
36  		String displayName = null;
37  		try {
38  			if (entity.isNodeType(PeopleTypes.PEOPLE_PERSON)) {
39  				String lastName = ConnectJcrUtils.get(entity, PEOPLE_LAST_NAME);
40  				String firstName = ConnectJcrUtils.get(entity, PEOPLE_FIRST_NAME);
41  				if (notEmpty(firstName) || notEmpty(lastName)) {
42  					displayName = lastName;
43  					if (notEmpty(firstName) && notEmpty(lastName))
44  						displayName += ", ";
45  					displayName += firstName;
46  				}
47  			} else if (entity.isNodeType(PeopleTypes.PEOPLE_ORG)) {
48  				// Default display is simply the legal name
49  				displayName = ConnectJcrUtils.get(entity, PEOPLE_LEGAL_NAME);
50  			} else
51  				throw new PeopleException("Display name not defined for type " + entity.getPrimaryNodeType().getName()
52  						+ " - node: " + entity);
53  		} catch (RepositoryException e) {
54  			throw new PeopleException("Unable to get display name for node " + entity, e);
55  		}
56  		return displayName;
57  	}
58  
59  	@Override
60  	public Node saveEntity(Node entity, boolean commit) throws PeopleException, RepositoryException {
61  		if (entity.isNodeType(PeopleTypes.PEOPLE_PERSON))
62  			return savePerson(entity, commit);
63  		else if (entity.isNodeType(PeopleTypes.PEOPLE_ORG))
64  			return saveOrganisation(entity, commit);
65  		else
66  			throw new PeopleException("Cannot save " + entity + ", Unknown entity type");
67  	}
68  
69  	/**
70  	 * Business specific save of a business object of type person. Among other, it
71  	 * updates cache information. Extend to provide business specific rules before
72  	 * save and commit
73  	 */
74  	protected Node savePerson(Node person, boolean publish) throws PeopleException, RepositoryException {
75  		String lastName = ConnectJcrUtils.get(person, PeopleNames.PEOPLE_LAST_NAME);
76  		String firstName = ConnectJcrUtils.get(person, PeopleNames.PEOPLE_FIRST_NAME);
77  		String displayName = ConnectJcrUtils.get(person, PEOPLE_DISPLAY_NAME);
78  
79  		// Check validity of main info
80  		if (isEmpty(lastName) && isEmpty(firstName) && isEmpty(displayName)) {
81  			String msg = "Please note that you must define a first name, a "
82  					+ "last name or a display name to be able to create or " + "update this person.";
83  			throw new PeopleException(msg);
84  		}
85  
86  		// Update display name cache if needed
87  		if (isEmpty(displayName))
88  			displayName = getDefaultDisplayName(person);
89  
90  		person.setProperty(Property.JCR_TITLE, displayName);
91  
92  		// person = peopleService.checkPathAndMoveIfNeeded(person,
93  		// PeopleTypes.PEOPLE_PERSON);
94  		// ConnectJcrUtils.saveAndPublish(person, false);
95  
96  		// Update cache
97  		peopleService.updatePrimaryCache(person);
98  		ConnectJcrUtils.saveAndPublish(person, publish);
99  		return person;
100 	}
101 
102 	/** Override to provide business specific rules before save and commit */
103 	protected Node saveOrganisation(Node org, boolean publish) throws PeopleException, RepositoryException {
104 		// Check validity of main info
105 		String legalName = ConnectJcrUtils.get(org, PeopleNames.PEOPLE_LEGAL_NAME);
106 		String displayName = ConnectJcrUtils.get(org, PEOPLE_DISPLAY_NAME);
107 
108 		// Check validity of main info
109 		if (isEmpty(legalName) && isEmpty(displayName)) {
110 			String msg = "Please note that you must define a legal or a display name "
111 					+ "to be able to create or update this organisation.";
112 			throw new PeopleException(msg);
113 		}
114 
115 		// Update display name cache if needed
116 		if (isEmpty(displayName))
117 			displayName = getDefaultDisplayName(org);
118 
119 		org.setProperty(Property.JCR_TITLE, displayName);
120 
121 		// org = peopleService.checkPathAndMoveIfNeeded(org,
122 		// PeopleTypes.PEOPLE_ORG);
123 		// Update cache
124 		peopleService.updatePrimaryCache(org);
125 		// real save
126 		ConnectJcrUtils.saveAndPublish(org, publish);
127 		return org;
128 	}
129 
130 	@Override
131 	public Node createOrUpdateJob(Node oldJob, Node person, Node organisation, String position, String department,
132 			boolean isPrimary) {
133 
134 		// The job on which to update various info
135 		Node newJob = null;
136 
137 		try {
138 			// First check if we must remove the old job when linked person has
139 			// changed
140 			if (oldJob != null) {
141 				Node oldPerson = oldJob.getParent().getParent();
142 				String oldPath = oldPerson.getPath();
143 				String newPath = person.getPath();
144 				if (!newPath.equals(oldPath)) {
145 					ConnectJcrUtils.checkCOStatusBeforeUpdate(oldPerson);
146 					oldJob.remove();
147 					// FIXME we should not save the session anymore
148 					oldPerson.getSession().save();
149 				} else
150 					newJob = oldJob;
151 			}
152 
153 			// Define the job node new name
154 			String orgName = ConnectJcrUtils.get(organisation, PeopleNames.PEOPLE_LEGAL_NAME);
155 			String orgUid = ConnectJcrUtils.get(organisation, ConnectNames.CONNECT_UID);
156 			String newNodeName = null;
157 			if (notEmpty(orgName)) {
158 				newNodeName = JcrUtils.replaceInvalidChars(orgName);
159 				// FIXME centralize this
160 				if (newNodeName.indexOf("\n") > -1)
161 					newNodeName = newNodeName.replaceAll("(?:\n)", "");
162 			} else
163 				newNodeName = orgUid;
164 
165 			ConnectJcrUtils.checkCOStatusBeforeUpdate(person);
166 			// Create node if necessary
167 			if (newJob == null) {
168 				Node parentNode = JcrUtils.mkdirs(person, PeopleNames.PEOPLE_JOBS, NodeType.NT_UNSTRUCTURED);
169 				newJob = parentNode.addNode(newNodeName.trim());
170 				newJob.addMixin(PeopleTypes.PEOPLE_JOB);
171 			} else if (!newNodeName.equals(newJob.getName())) {
172 				Session session = newJob.getSession();
173 				String srcAbsPath = newJob.getPath();
174 				String destAbsPath = JcrUtils.parentPath(srcAbsPath) + "/" + newNodeName.trim();
175 				session.move(srcAbsPath, destAbsPath);
176 			}
177 
178 			// Update properties
179 			// Related org
180 			newJob.setProperty(PeopleNames.PEOPLE_REF_UID, orgUid);
181 
182 			// position
183 			if (isEmpty(position) && newJob.hasProperty(PeopleNames.PEOPLE_ROLE))
184 				newJob.getProperty(PeopleNames.PEOPLE_ROLE).remove();
185 			else
186 				newJob.setProperty(PeopleNames.PEOPLE_ROLE, position);
187 
188 			// department
189 			if (isEmpty(department) && newJob.hasProperty(PeopleNames.PEOPLE_DEPARTMENT))
190 				newJob.getProperty(PeopleNames.PEOPLE_DEPARTMENT).remove();
191 			else
192 				newJob.setProperty(PeopleNames.PEOPLE_DEPARTMENT, department);
193 
194 			// primary flag
195 			if (isPrimary)
196 				PeopleJcrUtils.markAsPrimary(resourceService, peopleService, person, newJob);
197 			else
198 				newJob.setProperty(PeopleNames.PEOPLE_IS_PRIMARY, isPrimary);
199 			// FIXME we should not save the session anymore
200 			person.getSession().save();
201 		} catch (RepositoryException re) {
202 			throw new PeopleException(
203 					"unable to create or update job " + oldJob + " for person " + person + " and org " + organisation,
204 					re);
205 		}
206 		return null;
207 	}
208 }