KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > alfresco > repo > webservice > administration > AdministrationWebService


1 /*
2  * Copyright (C) 2005 Alfresco, Inc.
3  *
4  * Licensed under the Mozilla Public License version 1.1
5  * with a permitted attribution clause. You may obtain a
6  * copy of the License at
7  *
8  * http://www.alfresco.org/legal/license.txt
9  *
10  * Unless required by applicable law or agreed to in writing,
11  * software distributed under the License is distributed on an
12  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
13  * either express or implied. See the License for the specific
14  * language governing permissions and limitations under the
15  * License.
16  */

17 package org.alfresco.repo.webservice.administration;
18
19 import java.io.Serializable JavaDoc;
20 import java.rmi.RemoteException JavaDoc;
21 import java.text.MessageFormat JavaDoc;
22 import java.util.ArrayList JavaDoc;
23 import java.util.HashMap JavaDoc;
24 import java.util.HashSet JavaDoc;
25 import java.util.List JavaDoc;
26 import java.util.Map JavaDoc;
27 import java.util.Set JavaDoc;
28
29 import org.alfresco.model.ContentModel;
30 import org.alfresco.repo.cache.SimpleCache;
31 import org.alfresco.repo.transaction.TransactionComponent;
32 import org.alfresco.repo.transaction.TransactionUtil;
33 import org.alfresco.repo.transaction.TransactionUtil.TransactionWork;
34 import org.alfresco.repo.webservice.AbstractWebService;
35 import org.alfresco.repo.webservice.Utils;
36 import org.alfresco.repo.webservice.action.ActionFault;
37 import org.alfresco.repo.webservice.repository.QuerySession;
38 import org.alfresco.repo.webservice.types.NamedValue;
39 import org.alfresco.service.cmr.repository.NodeRef;
40 import org.alfresco.service.cmr.repository.datatype.DefaultTypeConverter;
41 import org.alfresco.service.cmr.security.AuthenticationService;
42 import org.alfresco.service.cmr.security.PersonService;
43 import org.alfresco.service.namespace.QName;
44 import org.alfresco.util.GUID;
45 import org.apache.axis.MessageContext;
46 import org.apache.commons.logging.Log;
47 import org.apache.commons.logging.LogFactory;
48
49 /**
50  * @author Roy Wetherall
51  */

52 public class AdministrationWebService extends AbstractWebService implements
53         AdministrationServiceSoapPort
54 {
55     /** Log */
56     private static Log logger = LogFactory.getLog(AdministrationWebService.class);
57     
58     /** The person service */
59     private PersonService personService = null;
60     
61     /** The authentication service */
62     private AuthenticationService authenticationService = null;
63     
64     /** The transaction service */
65     private TransactionComponent transactionService = null;
66     
67     /** A set of ignored properties */
68     private static Set JavaDoc<QName> ignoredProperties = new HashSet JavaDoc<QName>(3);
69     
70     /** Simple cache used to store user query sessions */
71     private SimpleCache<String JavaDoc, UserQuerySession> querySessionCache;
72     
73     /**
74      * Constructor
75      */

76     public AdministrationWebService()
77     {
78         // Set properties to ignore
79
AdministrationWebService.ignoredProperties.add(ContentModel.PROP_STORE_PROTOCOL);
80         AdministrationWebService.ignoredProperties.add(ContentModel.PROP_STORE_IDENTIFIER);
81         AdministrationWebService.ignoredProperties.add(ContentModel.PROP_NODE_UUID);
82     }
83     
84     /**
85      * Set the transaction service
86      *
87      * @param transactionService the transaction service
88      */

89     public void setTransactionService(TransactionComponent transactionService)
90     {
91         this.transactionService = transactionService;
92     }
93     
94     /**
95      * Set the person service
96      *
97      * @param personService sets the person service
98      */

99     public void setPersonService(PersonService personService)
100     {
101         this.personService = personService;
102     }
103     
104     /**
105      * Set the authentication service
106      *
107      * @param authenticationService the authentication service
108      */

109     public void setAuthenticationService(AuthenticationService authenticationService)
110     {
111         this.authenticationService = authenticationService;
112     }
113     
114     /**
115      * Sets the instance of the SimpleCache to be used
116      *
117      * @param querySessionCache
118      * The SimpleCache
119      */

120     public void setQuerySessionCache(
121             SimpleCache<String JavaDoc, UserQuerySession> querySessionCache)
122     {
123         this.querySessionCache = querySessionCache;
124     }
125     
126     /**
127      * @see org.alfresco.repo.webservice.administration.AdministrationServiceSoapPort#queryUsers(org.alfresco.repo.webservice.administration.UserFilter)
128      */

129     public UserQueryResults queryUsers(final UserFilter filter)
130             throws RemoteException JavaDoc, AdministrationFault
131     {
132         try
133         {
134             return TransactionUtil.executeInUserTransaction(this.transactionService, new TransactionWork<UserQueryResults>()
135             {
136                 public UserQueryResults doWork() throws Exception JavaDoc
137                 {
138                     return queryUsersImpl(filter);
139                 }
140             });
141         }
142         catch (Throwable JavaDoc exception)
143         {
144             if (logger.isDebugEnabled())
145             {
146                 logger.error("Unexpected error occurred", exception);
147             }
148             
149             throw new ActionFault(0, exception.getMessage());
150         }
151     }
152
153     /**
154      * Query users, batch by set size
155      *
156      * @param filter used to filter results
157      * @return user query results, optionally batched
158      */

159     private UserQueryResults queryUsersImpl(UserFilter filter)
160     {
161         MessageContext msgContext = MessageContext.getCurrentContext();
162         
163         // Create a user query session
164
UserQuerySession userQuerySession = new UserQuerySession(Utils.getBatchSize(msgContext), filter);
165         UserQueryResults userQueryResults = userQuerySession.getNextBatch();
166
167         // add the session to the cache if there are more results to come
168
if (userQueryResults.getQuerySession() != null)
169         {
170             // this.querySessionCache.putQuerySession(querySession);
171
this.querySessionCache.put(userQueryResults.getQuerySession(), userQuerySession);
172         }
173         
174         return userQueryResults;
175     }
176
177     /**
178      * @see org.alfresco.repo.webservice.administration.AdministrationServiceSoapPort#fetchMoreUsers(java.lang.String)
179      */

180     public UserQueryResults fetchMoreUsers(final String JavaDoc querySession)
181             throws RemoteException JavaDoc, AdministrationFault
182     {
183         try
184         {
185             return TransactionUtil.executeInUserTransaction(this.transactionService, new TransactionWork<UserQueryResults>()
186             {
187                 public UserQueryResults doWork() throws Exception JavaDoc
188                 {
189                     return fetchMoreUsersImpl(querySession);
190                 }
191             });
192         }
193         catch (Throwable JavaDoc exception)
194         {
195             if (logger.isDebugEnabled())
196             {
197                 logger.error("Unexpected error occurred", exception);
198             }
199             
200             throw new ActionFault(0, exception.getMessage());
201         }
202     }
203
204     /**
205      *
206      * @param querySession
207      * @return
208      */

209     private UserQueryResults fetchMoreUsersImpl(String JavaDoc querySession)
210     {
211         UserQueryResults queryResult = null;
212         UserQuerySession session = this.querySessionCache.get(querySession);
213         
214         if (session != null)
215         {
216             queryResult = session.getNextBatch();
217             if (queryResult.getQuerySession() == null)
218             {
219                 this.querySessionCache.remove(querySession);
220             }
221         }
222         
223         return queryResult;
224     }
225
226     /**
227      * @see org.alfresco.repo.webservice.administration.AdministrationServiceSoapPort#getUser(java.lang.String)
228      */

229     public UserDetails getUser(final String JavaDoc userName) throws RemoteException JavaDoc, AdministrationFault
230     {
231         try
232         {
233             return TransactionUtil.executeInUserTransaction(this.transactionService, new TransactionWork<UserDetails>()
234             {
235                 public UserDetails doWork() throws Exception JavaDoc
236                 {
237                     return getUserImpl(userName);
238                 }
239             });
240         }
241         catch (Throwable JavaDoc exception)
242         {
243             if (logger.isDebugEnabled())
244             {
245                 logger.error("Unexpected error occurred", exception);
246             }
247             
248             throw new ActionFault(0, exception.getMessage());
249         }
250     }
251     
252     /**
253      * Get the user details
254      *
255      * @param userName the user name
256      * @return the user details object
257      * @throws RemoteException
258      * @throws AdministrationFault
259      */

260     private UserDetails getUserImpl(String JavaDoc userName)
261     {
262         UserDetails userDetails = null;
263         
264         if (this.personService.personExists(userName) == true)
265         {
266             NodeRef nodeRef = this.personService.getPerson(userName);
267             userDetails = createUserDetails(userName, nodeRef);
268         }
269         else
270         {
271             // Throw an exception to indicate that the user does not exist
272
throw new RuntimeException JavaDoc(MessageFormat.format("The user with name {0} does not exist.", new Object JavaDoc[]{userName}));
273         }
274         
275         return userDetails;
276     }
277
278     /**
279      * Given a valid person node reference will create a user details object
280      *
281      * @param nodeRef the node reference
282      * @return the user details object populated with the appropriate property values
283      */

284     private UserDetails createUserDetails(String JavaDoc userName, NodeRef nodeRef)
285     {
286         // Create the user details object
287
UserDetails userDetails = new UserDetails();
288         
289         // Set the user name
290
userDetails.setUserName(userName);
291         
292         // Set the various property values
293
Map JavaDoc<QName, Serializable JavaDoc> properties = this.nodeService.getProperties(nodeRef);
294         List JavaDoc<NamedValue> namedValues = new ArrayList JavaDoc<NamedValue>(properties.size());
295         for (Map.Entry JavaDoc<QName, Serializable JavaDoc> entry : properties.entrySet())
296         {
297             if (AdministrationWebService.ignoredProperties.contains(entry.getKey()) == false)
298             {
299                 String JavaDoc value = null;
300                 try
301                 {
302                     value = DefaultTypeConverter.INSTANCE.convert(String JavaDoc.class, entry.getValue());
303                 }
304                 catch (Throwable JavaDoc exception)
305                 {
306                     value = entry.getValue().toString();
307                 }
308                 namedValues.add(new NamedValue(entry.getKey().toString(), value));
309             }
310         }
311         userDetails.setProperties((NamedValue[])namedValues.toArray(new NamedValue[namedValues.size()]));
312         
313         return userDetails;
314     }
315
316     /**
317      * @see org.alfresco.repo.webservice.administration.AdministrationServiceSoapPort#createUsers(org.alfresco.repo.webservice.administration.NewUserDetails[])
318      */

319     public UserDetails[] createUsers(final NewUserDetails[] newUsers) throws RemoteException JavaDoc, AdministrationFault
320     {
321         try
322         {
323             return TransactionUtil.executeInUserTransaction(this.transactionService, new TransactionWork<UserDetails[]>()
324             {
325                 public UserDetails[] doWork() throws Exception JavaDoc
326                 {
327                     return createUsersImpl(newUsers);
328                 }
329             });
330         }
331         catch (Throwable JavaDoc exception)
332         {
333             if (logger.isDebugEnabled())
334             {
335                 logger.error("Unexpected error occurred", exception);
336             }
337             
338             throw new ActionFault(0, exception.getMessage());
339         }
340     }
341     
342     /**
343      * Create the new users
344      *
345      * @param newUsers the new users detail
346      * @return the details of the created users
347      * @throws RemoteException
348      * @throws AdministrationFault
349      */

350     private UserDetails[] createUsersImpl(NewUserDetails[] newUsers)
351     {
352         UserDetails[] userDetails = new UserDetails[newUsers.length];
353         
354         int index = 0;
355         for (NewUserDetails newUser : newUsers)
356         {
357             // Create a new authentication
358
this.authenticationService.createAuthentication(newUser.getUserName(), newUser.getPassword().toCharArray());
359             
360             // Create a new person
361
Map JavaDoc<QName, Serializable JavaDoc> properties = new HashMap JavaDoc<QName, Serializable JavaDoc>(7);
362             properties.put(ContentModel.PROP_USERNAME, newUser.getUserName());
363             for (NamedValue namedValue : newUser.getProperties())
364             {
365                 properties.put(QName.createQName(namedValue.getName()), namedValue.getValue());
366             }
367             NodeRef personNodeRef = this.personService.createPerson(properties);
368             
369             // Add the details to the result
370
userDetails[index] = createUserDetails(newUser.getUserName(), personNodeRef);
371             index++;
372         }
373                 
374         return userDetails;
375     }
376
377     /**
378      * @see org.alfresco.repo.webservice.administration.AdministrationServiceSoapPort#updateUsers(org.alfresco.repo.webservice.administration.UserDetails[])
379      */

380     public UserDetails[] updateUsers(final UserDetails[] users) throws RemoteException JavaDoc, AdministrationFault
381     {
382         try
383         {
384             return TransactionUtil.executeInUserTransaction(this.transactionService, new TransactionWork<UserDetails[]>()
385             {
386                 public UserDetails[] doWork() throws Exception JavaDoc
387                 {
388                     return updateUsersImpl(users);
389                 }
390             });
391         }
392         catch (Throwable JavaDoc exception)
393         {
394             if (logger.isDebugEnabled())
395             {
396                 logger.error("Unexpected error occurred", exception);
397             }
398             
399             throw new ActionFault(0, exception.getMessage());
400         }
401     }
402     
403     /**
404      * Update the users details
405      *
406      * @param users the user details to update
407      * @return the updated user details
408      */

409     private UserDetails[] updateUsersImpl(UserDetails[] users)
410     {
411         UserDetails[] userDetails = new UserDetails[users.length];
412         
413         int index = 0;
414         for (UserDetails user : users)
415         {
416             // Build the property map
417
Map JavaDoc<QName, Serializable JavaDoc> properties = new HashMap JavaDoc<QName, Serializable JavaDoc>(7);
418             properties.put(ContentModel.PROP_USERNAME, user.getUserName());
419             for (NamedValue namedValue : user.getProperties())
420             {
421                 properties.put(QName.createQName(namedValue.getName()), namedValue.getValue());
422             }
423             
424             // Update the properties of the person
425
this.personService.setPersonProperties(user.getUserName(), properties);
426             
427             // Add the details to the result
428
NodeRef nodeRef = this.personService.getPerson(user.getUserName());
429             userDetails[index] = createUserDetails(user.getUserName(), nodeRef);
430             index++;
431         }
432                 
433         return userDetails;
434     }
435
436     /**
437      * @see org.alfresco.repo.webservice.administration.AdministrationServiceSoapPort#changePassword(java.lang.String, java.lang.String, java.lang.String)
438      */

439     public void changePassword(final String JavaDoc userName, final String JavaDoc oldPassword, final String JavaDoc newPassword) throws RemoteException JavaDoc, AdministrationFault
440     {
441         try
442         {
443             TransactionUtil.executeInUserTransaction(this.transactionService, new TransactionWork<Object JavaDoc>()
444             {
445                 public Object JavaDoc doWork() throws Exception JavaDoc
446                 {
447                     changePasswordImpl(userName, oldPassword, newPassword);
448                     return null;
449                 }
450             });
451         }
452         catch (Throwable JavaDoc exception)
453         {
454             if (logger.isDebugEnabled())
455             {
456                 logger.error("Unexpected error occurred", exception);
457             }
458             
459             throw new ActionFault(0, exception.getMessage());
460         }
461     }
462
463     /**
464      * Change the current password of the user
465      *
466      * @param userName the user name
467      * @param oldPassword the old (current) password
468      * @param newPassword the new password
469      */

470     private void changePasswordImpl(String JavaDoc userName, String JavaDoc oldPassword, String JavaDoc newPassword)
471     {
472         // Update the authentication details
473
this.authenticationService.updateAuthentication(userName, oldPassword.toCharArray(), newPassword.toCharArray());
474     }
475
476     /**
477      * @see org.alfresco.repo.webservice.administration.AdministrationServiceSoapPort#deleteUsers(java.lang.String[])
478      */

479     public void deleteUsers(final String JavaDoc[] userNames) throws RemoteException JavaDoc,
480             AdministrationFault
481     {
482         try
483         {
484             TransactionUtil.executeInUserTransaction(this.transactionService, new TransactionWork<Object JavaDoc>()
485             {
486                 public Object JavaDoc doWork() throws Exception JavaDoc
487                 {
488                     deleteUsersImpl(userNames);
489                     return null;
490                 }
491             });
492         }
493         catch (Throwable JavaDoc exception)
494         {
495             if (logger.isDebugEnabled())
496             {
497                 logger.error("Unexpected error occurred", exception);
498             }
499             
500             throw new ActionFault(0, exception.getMessage());
501         }
502     }
503
504     /**
505      * Delete users
506      *
507      * @param userNames the names of the users to delete
508      */

509     private void deleteUsersImpl(String JavaDoc[] userNames)
510     {
511         for (String JavaDoc userName : userNames)
512         {
513             this.personService.deletePerson(userName);
514         }
515     }
516     
517     /**
518      * User query session used to support batched user query
519      *
520      * @author Roy Wetherall
521      */

522     private class UserQuerySession implements Serializable JavaDoc
523     {
524         private static final long serialVersionUID = -2960711874297744356L;
525         
526         private int batchSize = -1;
527         private UserFilter filter;
528         protected int position = 0;
529         private String JavaDoc id;
530         
531         /**
532          * Constructor
533          *
534          * @param batchSize
535          * @param filter
536          */

537         public UserQuerySession(int batchSize, UserFilter filter)
538         {
539             this.batchSize = batchSize;
540             this.filter = filter;
541             this.id = GUID.generate();
542         }
543                 
544         /**
545          * @see org.alfresco.repo.webservice.repository.QuerySession#getId()
546          */

547         public String JavaDoc getId()
548         {
549            return this.id;
550         }
551       
552         /**
553          * Calculates the index of the last row to retrieve.
554          *
555          * @param totalRowCount The total number of rows in the results
556          * @return The index of the last row to return
557          */

558         protected int calculateLastRowIndex(int totalRowCount)
559         {
560            int lastRowIndex = totalRowCount;
561            
562            // set the last row index if there are more results available
563
// than the batch size
564
if ((this.batchSize != -1) && ((this.position + this.batchSize) < totalRowCount))
565            {
566               lastRowIndex = this.position + this.batchSize;
567            }
568            
569            return lastRowIndex;
570         }
571         
572         /**
573          * Calculates the value of the next position.
574          * If the end of the result set is reached the position is set to -1
575          *
576          * @param totalRowCount The total number of rows in the results
577          * @param queryResult The QueryResult object being returned to the client,
578          * if there are no more results the id is removed from the QueryResult instance
579          */

580         protected void updatePosition(int totalRowCount, UserQueryResults queryResult)
581         {
582            if (this.batchSize == -1)
583            {
584                this.position = -1;
585                queryResult.setQuerySession(null);
586            }
587            else
588            {
589                this.position += this.batchSize;
590                if (this.position >= totalRowCount)
591                {
592                   // signify that there are no more results
593
this.position = -1;
594                   queryResult.setQuerySession(null);
595                }
596            }
597         }
598         
599         /**
600          * Gets the next batch of user details
601          *
602          * @return user query results
603          */

604         public UserQueryResults getNextBatch()
605         {
606             UserQueryResults queryResult = null;
607             
608             if (this.position != -1)
609             {
610                if (logger.isDebugEnabled())
611                   logger.debug("Before getNextBatch: " + toString());
612                
613                Set JavaDoc<NodeRef> nodeRefs = AdministrationWebService.this.personService.getAllPeople();
614                
615                // TODO do the filter of the resulting list here ....
616
List JavaDoc<NodeRef> filteredNodeRefs = new ArrayList JavaDoc<NodeRef>(nodeRefs);
617                
618                int totalRows = filteredNodeRefs.size();
619                int lastRow = calculateLastRowIndex(totalRows);
620                int currentBatchSize = lastRow - this.position;
621                
622                if (logger.isDebugEnabled())
623                   logger.debug("Total rows = " + totalRows + ", current batch size = " + currentBatchSize);
624                
625                List JavaDoc<UserDetails> userDetailsList = new ArrayList JavaDoc<UserDetails>(currentBatchSize);
626                
627                for (int x = this.position; x < lastRow; x++)
628                {
629                   NodeRef nodeRef = (NodeRef)filteredNodeRefs.get(x);
630                   String JavaDoc userName = (String JavaDoc)AdministrationWebService.this.nodeService.getProperty(nodeRef, ContentModel.PROP_USERNAME);
631                   UserDetails userDetails = AdministrationWebService.this.createUserDetails(userName, nodeRef);
632                   userDetailsList.add(userDetails);
633                }
634                
635                queryResult = new UserQueryResults(getId(), (UserDetails[])userDetailsList.toArray(new UserDetails[userDetailsList.size()]));
636                
637                // move the position on
638
updatePosition(totalRows, queryResult);
639                
640                if (logger.isDebugEnabled())
641                   logger.debug("After getNextBatch: " + toString());
642             }
643             
644             return queryResult;
645         }
646     }
647 }
648
Popular Tags