4A Server -  2.0
 All Classes Namespaces Files Functions Variables Enumerator
PersonsModule.java
Go to the documentation of this file.
1 /*
2  * Project: Server for annotations sharing
3  * Author: Ing. Jaroslav Dytrych idytrych@fit.vutbr.cz
4  * File: PersonsModule.java
5  * Description: This module implements operations with persons
6  * (users of this server) and with user groups.
7  *
8  */
9 
10 /**
11  * @file PersonsModule.java
12  *
13  * @brief Operations with persons (users of this server) and with user groups
14  */
15 
16 /**
17  * @package cz.vutbr.fit.knot.annotations.modules
18  *
19  * @brief Modules with server functionality
20  */
21 package cz.vutbr.fit.knot.annotations.modules;
22 
33 import java.util.ArrayList;
34 import java.util.Arrays;
35 import java.util.Iterator;
36 import java.util.List;
37 import java.util.logging.Level;
38 import java.util.logging.Logger;
39 import javax.persistence.EntityManager;
40 import javax.persistence.Query;
41 
42 /**
43  * Class which performs operations with persons (users of this server)
44  * and with user groups
45  *
46  * @brief Operations with persons (users of this server) and with user groups
47  * @author idytrych
48  */
49 public class PersonsModule implements AnnotServerModule {
50 
51  /**
52  * This method is called when client sent message and these message
53  * has been processed. Changes in types, annotations and in other entities
54  * are persisted after calling this method from all modules.
55  *
56  * @param requestInfo Info about client request
57  * @return String with messages for client or empty string
58  */
59  @Override
60  public String processRequestBeforePersist(RequestInfo requestInfo) {
61  return "";
62  }
63 
64  /**
65  * This method is called when client sent message, these message
66  * has been processed and changes in entities are persisted.
67  * Composed response is sent to client after calling this method from
68  * all modules.
69  * It performs:
70  * - creating message with queried persons
71  * - creating message with queried user groups
72  *
73  * @param requestInfo Informations about client request
74  * @param persistFailed True if changes not persisted, false otherwise.
75  * @return String with messages for client or empty string
76  */
77  @Override
78  public String processRequestAfterPersist(RequestInfo requestInfo, boolean persistFailed) {
79  String retString = "";
80  // create message from queried persons
81  if (!requestInfo.getQueryPersons().isEmpty()) {
82  Iterator<String> reqIter = requestInfo.getQueryPersons().iterator();
83  retString = retString + processQP(reqIter, false, requestInfo);
84  }
85  // create message from queried persons with user groups
86  if (!requestInfo.getQueryPersonsWG().isEmpty()) {
87  Iterator<String> reqIter = requestInfo.getQueryPersonsWG().iterator();
88  retString = retString + processQP(reqIter, true, requestInfo);
89  }
90  // create message from queried user groups
91  if (!requestInfo.getQueryUserGroups().isEmpty()) {
92  Iterator<String> reqIter = requestInfo.getQueryUserGroups().iterator();
93  retString = retString + processQUG(reqIter, false, requestInfo);
94  }
95  // create message from queried user groups with persons
96  if (!requestInfo.getQueryUserGroupsWP().isEmpty()) {
97  Iterator<String> reqIter = requestInfo.getQueryUserGroupsWP().iterator();
98  retString = retString + processQUG(reqIter, true, requestInfo);
99  }
100  // create message from queried persons for protocol version 2.0
101  if(requestInfo.getUsersQueryV2() != null && !requestInfo.getUsersQueryV2().isEmpty()){
102  ArrayList<User> users = userQuerry(requestInfo.getUsersQueryV2());
103  retString = retString + P2MessagesCreator.getXMLUsersList(users,requestInfo.getUsersRestrictionsV2());
104  }
105  // create message from queried users groups for protocol version 2.0
106  if(requestInfo.getGroupsQueryV2() != null && !requestInfo.getGroupsQueryV2().isEmpty()){
107  ArrayList<UserGroup> groups = groupQuerry(requestInfo.getGroupsQueryV2());
108  boolean withUsers = false;
109  if(requestInfo.getGroupsQueryV2().get(P2Constants.GROUPS_Q_W_USERS).equals("true")){
110  withUsers = true;
111  }
112  retString = retString + P2MessagesCreator.getXMLGroupsList(groups,withUsers,requestInfo.getUsersGroupRestrictionsV2());
113  }
114 
115  return retString;
116  } // processRequestAfterPersist()
117 
118  /**
119  * Gets queried user groups in XML string
120  *
121  * @param reqIter Iterator to array with filters (queries)
122  * @param withPersons If persons have to be included, then true, false otherwise
123  * @param requestInfo Informations about client request
124  * @return Returns XML string with queried user groups
125  */
126  public String processQUG(Iterator<String> reqIter, Boolean withPersons, RequestInfo requestInfo) {
127  String retString = "";
128  while (reqIter.hasNext()) { // for each filter (query)
129  String reqStr = reqIter.next();
130  List gList = null;
131  if (reqStr.contains(AppBean.getBaseGroupUri())) { // if filter contains URI of group
132  // get id from group by stripping off base URI
133  String idStr = reqStr.replace(AppBean.getBaseGroupUri(), "");
134  // parse id
135  Integer reqId = null;
136  try {
137  Integer id = Integer.parseInt(idStr);
138  } catch (NumberFormatException nfe) {
140  String msg = "Bad id of group in the query message: " + idStr;
141  Logger.getLogger(PersonsModule.class.getName()).log(Level.SEVERE, msg, nfe);
142  }
143  continue; // if id is bad, no results for this query
144  }
145  // query database for group
146  Object[] params = new Object[2];
147  params[0] = "id";
148  params[1] = reqId;
149  gList = AppBean.getPersistenceManager().queryDB("UserGroup.findById", params);
150  } else { // if filter contains name of group
151  EntityManager em = AppBean.getPersistenceManager().getEM();
152  String reqName = reqStr.replace("*", "%"); // replace wildcards by those used by database
153  // query database
154  String gQStr = "SELECT u FROM UserGroup u WHERE u.name LIKE '" + reqName + "'";
155  try {
156  Query query = em.createQuery(gQStr);
157  gList = query.getResultList();
158  } catch (Exception e) {
160  String msg = "Exception during the query for user groups.";
161  Logger.getLogger(PersonsModule.class.getName()).log(Level.SEVERE, msg);
162  }
163  gList = null;
164  } finally {
165  em.close();
166  }
167  } // if filter contains name of group
168 
169  if (gList != null && !gList.isEmpty() && withPersons) {
170  // if user groups was found and have to be returned with persons
171  Iterator gIter = gList.iterator();
172  while (gIter.hasNext()) { // for each found user group
173  UserGroup uGroup = (UserGroup) gIter.next();
174  retString = retString + uGroup.toXMLStringWP(); // serialize
175  }
176  } else if (gList != null && !gList.isEmpty()) {
177  // if user groups was found
178  Iterator gIter = gList.iterator();
179  while (gIter.hasNext()) { // for each found user group
180  UserGroup uGroup = (UserGroup) gIter.next();
181  retString = retString + uGroup.toXMLString(); // serialize
182  }
183  }
184  } // for each filter (query)
185 
186  // surround with userGroups message
187  retString = "<userGroups>" + retString + "</userGroups>";
188  return retString;
189  } // processQUG()
190 
191  /**
192  * Gets queried persons (users) in XML string
193  *
194  * @param reqIter Iterator to array with filters (queries)
195  * @param withGroups If users groups have to be included, then true, false otherwise
196  * @param requestInfo Informations about client request
197  * @return Returns XML string with queried persons
198  */
199  public String processQP(Iterator<String> reqIter, Boolean withGroups, RequestInfo requestInfo) {
200  String retString = "";
201  while (reqIter.hasNext()) { // for each filter (query)
202  String reqStr = reqIter.next();
203  Integer reqId = null;
204  String reqName = null;
205  String reqEmail = null;
206 
207  // get attributes of person from filter (split fields of filter)
208  String[] reqAttrArray = reqStr.split(";");
209  ArrayList<String> reqAttributes = new ArrayList<String>(Arrays.asList(reqAttrArray));
210  Iterator<String> reqAttrIterator = reqAttributes.iterator();
211  while (reqAttrIterator.hasNext()) { // for each attribute of person (field of filter)
212  String reqAttr = reqAttrIterator.next();
213  if (reqAttr.indexOf(" ") == 0) { // trim leading white space
214  reqAttr = reqAttr.substring(1, reqAttr.length());
215  }
216  if (reqAttr.indexOf("id:") == 0) { // if this field contains id (URI)
217  String reqIdStr = reqAttr.substring(3, reqAttr.length()); // remove field name
218  if (reqIdStr.indexOf(" ") == 0) { // trim leading white space
219  reqIdStr = reqIdStr.substring(1, reqIdStr.length());
220  }
221  // remove base URI
222  reqIdStr = reqIdStr.replace(AppBean.getBaseAuthorUri(), "");
223  try {
224  // parse id
225  reqId = Integer.parseInt(reqIdStr);
226  } catch (NumberFormatException nfe) {
228  String msg = "Bad id of person in the query message: " + reqIdStr;
229  Logger.getLogger(PersonsModule.class.getName()).log(Level.SEVERE, msg, nfe);
230  }
231  reqId = null;
232  }
233  } else if (reqAttr.indexOf("email:") == 0) { // if this field contains email
234  reqEmail = reqAttr.substring(6, reqAttr.length()); // remove field name
235  if (reqEmail.indexOf(" ") == 0) { // trim leading white space
236  reqEmail = reqEmail.substring(1, reqEmail.length());
237  }
238  } else if (reqAttr.indexOf("name:") == 0) { // if this field contains full name
239  reqName = reqAttr.substring(5, reqAttr.length()); // remove field name
240  if (reqName.indexOf(" ") == 0) { // trim leading white space
241  reqName = reqName.substring(1, reqName.length());
242  }
243  } else if (reqAttr.indexOf(AppBean.getBaseAuthorUri()) == 0) { // if this field contains URI (id)
244  // remove base URI
245  String reqIdStr = reqAttr.substring(AppBean.getBaseAuthorUri().length(), reqAttr.length());
246  try {
247  // parse id of user
248  reqId = Integer.parseInt(reqIdStr);
249  } catch (NumberFormatException nfe) {
251  String msg = "Bad id of person in the query message (in URI): " + reqIdStr;
252  Logger.getLogger(PersonsModule.class.getName()).log(Level.SEVERE, msg, nfe);
253  }
254  reqId = null;
255  }
256  } else if (reqAttr.indexOf("@") > 0 && reqEmail == null) { // if this field probably contains email
257  reqEmail = reqAttr;
258  } else if (reqName == null) { // if full name was not set, this field probably contains it
259  reqName = reqAttr;
260  }
261  // unknown attributes are omitted
262  } // for each attribute of person (field of filter)
263 
264  // default if find by name and email
265  String qStr = "User.findByNameAndEmail";
266  String fQStr = null;
267  Object[] params = null;
268  if (reqId != null) { // if id is set, it will be used instead
269  qStr = "User.findById";
270  params = new Object[2];
271  params[0] = "id";
272  params[1] = reqId;
273  } else if (reqEmail != null && reqName != null) { // if email and name are set
274  if (reqName.contains("*") && reqEmail.contains("*")) { // if wildcards are used in both
275  reqName = reqName.replace("*", "%"); // replace wildcards by those used by database
276  reqEmail = reqEmail.replace("*", "%");
277  // special query must be used
278  fQStr = "SELECT u FROM User u WHERE u.name LIKE '" + reqName + "' AND u.email LIKE '" + reqEmail + "'";
279  } else if (reqEmail.contains("*")) { // if wildcards are used in email only
280  reqEmail = reqEmail.replace("*", "%");
281  // special query must be used
282  fQStr = "SELECT u FROM User u WHERE u.name LIKE '" + reqName + "' AND u.email = '" + reqEmail + "'";
283  } else if (reqName.contains("*")) { // if wildcards are used in full name only
284  reqName = reqName.replace("*", "%");
285  // special query must be used
286  fQStr = "SELECT u FROM User u WHERE u.name = '" + reqName + "' AND u.email LIKE '" + reqEmail + "'";
287  } else { // if wildcards aren't used, ordinary named query will be used
288  params = new Object[4];
289  params[0] = "name";
290  params[1] = reqName;
291  params[2] = "email";
292  params[3] = reqEmail;
293  }
294  } else if (reqName == null) { // if only email is set
295  if (reqEmail.contains("*")) { // if wildcards are used
296  reqEmail = reqEmail.replace("*", "%"); // replace wildcards by those used by database
297  // special query must be used
298  fQStr = "SELECT u FROM User u WHERE u.email LIKE '" + reqEmail + "'";
299  } else { // if wildcards aren't used, ordinary named query will be used
300  qStr = "User.findByEmail";
301  params = new Object[2];
302  params[0] = "email";
303  params[1] = reqEmail;
304  }
305  } else { // if only full name is set
306  if (reqName.contains("*")) { // if wildcards are used
307  reqName = reqName.replace("*", "%"); // replace wildcards by those used by database
308  // special query must be used
309  fQStr = "SELECT u FROM User u WHERE u.name LIKE '" + reqName + "'";
310  } else { // if wildcards aren't used, ordinary named query will be used
311  qStr = "User.findByName";
312  params = new Object[2];
313  params[0] = "name";
314  params[1] = reqName;
315  }
316  }
317  List uList = null;
318  if (fQStr != null) { // if special query must be used
319  EntityManager em = AppBean.getPersistenceManager().getEM();
320  try {
321  // query database
322  Query query = em.createQuery(fQStr);
323  uList = query.getResultList();
324  } catch (Exception e) {
326  String msg = "Exception during the query for persons.";
327  Logger.getLogger(PersonsModule.class.getName()).log(Level.SEVERE, msg);
328  }
329  uList = null;
330  } finally {
331  em.close();
332  }
333  } else { // if ordinary named query can be used
334  // query database
335  uList = AppBean.getPersistenceManager().queryDB(qStr, params);
336  }
337 
338  if (uList != null && !uList.isEmpty() && withGroups) {
339  // if persons was found and have to be returned with groups
340  Iterator uIter = uList.iterator();
341  while (uIter.hasNext()) { // for each found person
342  User user = (User) uIter.next();
343  retString = retString + user.toXMLStringWG(); // serialize
344  }
345  } else if (uList != null && !uList.isEmpty()) { // if persons was found
346  Iterator uIter = uList.iterator();
347  while (uIter.hasNext()) { // for each found person
348  User user = (User) uIter.next();
349  retString = retString + user.toXMLString(); // serialize
350  }
351  }
352  } // for each filter (query)
353 
354  // surround with persons message
355  retString = "<persons>" + retString + "</persons>";
356  return retString;
357  } // processQP()
358 
359  /**
360  * Gets queried user groups (for protocol 2.0 only)
361  *
362  * @param queryList List with informations about query (filters).
363  * For each filter criteria there is one position (index) in the list.
364  * Value of the filter is the value on the given index.
365  * @return Returns list of groups for gven query
366  */
367  @SuppressWarnings("unchecked")
368  private ArrayList<UserGroup> groupQuerry(ArrayList<String> queryList){
369  List<UserGroup> result = null;
370  boolean isWild = false;
371  boolean first = true;
372  String name = getWildcardPrefix(queryList.get(P2Constants.GROUPS_Q_NAME));
373 
374  if(name != null){
375  isWild = true;
376  }
377 
378  // make query string
379  StringBuilder queryStr = new StringBuilder();
380  queryStr.append("SELECT g FROM UserGroup g");
381 
382  // test id
383  if(!queryList.get(P2Constants.GROUPS_Q_ID).isEmpty()){
384  if(first){
385  queryStr.append(" WHERE g.id = '");
386  first = false;
387  }else{
388  queryStr.append(" AND g.id = '");
389  }
390 
391  queryStr.append(queryList.get(P2Constants.GROUPS_Q_ID));
392  queryStr.append("'");
393  }
394 
395  if(!queryList.get(P2Constants.GROUPS_Q_NAME).isEmpty()){
396  if(first){
397  queryStr.append(" WHERE g.name ");
398  first = false;
399  }else{
400  queryStr.append(" AND g.name ");
401  }
402 
403  if(isWild){
404  queryStr.append("LIKE '");
405  queryStr.append(name);
406  queryStr.append("%'");
407  }else{
408  queryStr.append("= '");
409  queryStr.append(queryList.get(P2Constants.GROUPS_Q_NAME));
410  queryStr.append("'");
411  }
412  }
413 
414  EntityManager em = AppBean.getPersistenceManager().getEM();
415  try {
416  // query database
417  Query query = em.createQuery(queryStr.toString());
418  result = query.getResultList();
419  } catch (Exception e) {
421  String msg = "Exception during the query for groups.";
422  Logger.getLogger(PersonsModule.class.getName()).log(Level.SEVERE, msg);
423  }
424  result = null;
425  } finally {
426  em.close();
427  }
428 
429  ArrayList<UserGroup> returnArray;
430  if(result == null){
431  returnArray = new ArrayList<UserGroup>();
432  }else{
433  returnArray = new ArrayList<UserGroup>(result);
434  }
435 
436  return returnArray;
437  } // groupQuerry()
438 
439  /**
440  * Gets queried users (for protocol 2.0 only)
441  *
442  * @param queryList List with informations about query (filters).
443  * For each filter criteria there is one position (index) in the list.
444  * Value of the filter is the value on the given index.
445  * @return Returns list of users for gven query
446  */
447  @SuppressWarnings("unchecked")
448  private ArrayList<User> userQuerry(ArrayList<String> queryList){
449  List<User> result = null;
450  UserGroup group = null;
451  boolean isWild = false;
452  boolean first = true;
453  String name = getWildcardPrefix(queryList.get(P2Constants.USERS_Q_NAME_ATTR));
454 
455  if(name != null){
456  isWild = true;
457  }
458 
459  // make query string
460  StringBuilder queryStr = new StringBuilder();
461  queryStr.append("SELECT u FROM User u");
462 
463  // test id
464  if(!queryList.get(P2Constants.USERS_Q_URI_ATTR).isEmpty()){
465  if(first){
466  queryStr.append(" WHERE u.id = '");
467  first = false;
468  }else{
469  queryStr.append(" AND u.id = '");
470  }
471 
472  queryStr.append(queryList.get(P2Constants.USERS_Q_URI_ATTR));
473  queryStr.append("'");
474  }
475 
476  // test user name
477  if(!queryList.get(P2Constants.USERS_Q_NAME_ATTR).isEmpty()){
478  if(first){
479  queryStr.append(" WHERE u.name ");
480  first = false;
481  }else{
482  queryStr.append(" AND u.name ");
483  }
484 
485  if(isWild){
486  queryStr.append("LIKE '");
487  queryStr.append(name);
488  queryStr.append("%'");
489  }else{
490  queryStr.append("= '");
491  queryStr.append(queryList.get(P2Constants.USERS_Q_NAME_ATTR));
492  queryStr.append("'");
493  }
494  }
495 
496  // test for email
497  if(!queryList.get(P2Constants.USERS_Q_EMAIL_ATTR).isEmpty()){
498  if(first){
499  queryStr.append(" WHERE u.email = '");
500  first = false;
501  }else{
502  queryStr.append(" AND u.email = '");
503  }
504 
505  queryStr.append(queryList.get(P2Constants.USERS_Q_EMAIL_ATTR));
506  queryStr.append("'");
507  }
508 
509  EntityManager em = AppBean.getPersistenceManager().getEM();
510  try {
511  // query database
512  Query query = em.createQuery(queryStr.toString());
513  result = query.getResultList();
514  if(!queryList.get(P2Constants.USERS_Q_GROUP_ATTR).isEmpty()){
515  String qStr2 = "SELECT u FROM UserGroup u WHERE u.id = '" + queryList.get(P2Constants.USERS_Q_GROUP_ATTR) + "'";
516  query = em.createQuery(qStr2);
517  group = (UserGroup)query.getSingleResult();
518  }
519  } catch (Exception e) {
521  String msg = "Exception during the query for persons.";
522  Logger.getLogger(PersonsModule.class.getName()).log(Level.SEVERE, msg);
523  }
524  result = null;
525  } finally {
526  em.close();
527  }
528 
529  //filter groups - if needed
530  if(group != null){
531  List<User> tmpArray;
532  tmpArray = group.getUsers();
533  result.retainAll(tmpArray);
534  }
535 
536  if(result != null)
537  return new ArrayList<User>(result);
538  else
539  return new ArrayList<User>();
540  } // userQuerry()
541 
542  /**
543  * Method checks whether the string contains wildchar "*". If the string
544  * contains wildchar the method returns prefix.
545  *
546  * @param value string in which will be searched
547  * @return prefix before wildchar or null if string don't contains wildchar
548  */
549  private String getWildcardPrefix(String value){
550  int index = value.indexOf('*');
551  if(index > 0){
552  return value.substring(0, index);
553  }else{
554  return null;
555  }
556  }
557 
558  /**
559  * This method is called for each sleeping comet handler when he receives
560  * flier (part of informations about this or another client request).
561  *
562  * In this module it always returns empty string.
563  *
564  * @param flier Flier, which has been sent to all comet handlers.
565  * @param session Session associated with comet handler.
566  * @return If this handler hasn't react to this flier (not interested) return
567  * null, else return messages for client in single string.
568  */
569  @Override
570  public String messagesFromFlier(Flier flier, EditorSession session) {
571  return "";
572  }
573 
574  /**
575  * Returns name of this module. Name will be included in XML element
576  * attribute so usable characters are restricted.
577  *
578  * @param lang Requested language of name
579  * @return Name of this module
580  */
581  @Override
582  public String getModuleName(int lang) {
583  return "Persons module";
584  }
585 
586  /**
587  * Returns description of this module. It will be part of information
588  * about server functions.
589  *
590  * @param lang Requested language of description
591  * @return Description of this module
592  */
593  @Override
594  public String getModuleDescription(int lang) {
595  return "Persons module performs processing of queryPersons and queryUserGroups messages.";
596  }
597 
598 } // class PersonsModule
String processQP(Iterator< String > reqIter, Boolean withGroups, RequestInfo requestInfo)
String processQUG(Iterator< String > reqIter, Boolean withPersons, RequestInfo requestInfo)
Singleton for storing global variables.
Definition: AppBean.java:47
String messagesFromFlier(Flier flier, EditorSession session)
Class representing user group.
Definition: UserGroup.java:47
ArrayList< User > userQuerry(ArrayList< String > queryList)
ArrayList< UserGroup > groupQuerry(ArrayList< String > queryList)
Class representing user.
Definition: User.java:51
Flier with informations for comet handlers.
Definition: Flier.java:31
String processRequestAfterPersist(RequestInfo requestInfo, boolean persistFailed)
Operations with persons (users of this server) and with user groups.
Processed informations about client request.
Informations about client session.
Class provides methods for transforming objects to messages.
String processRequestBeforePersist(RequestInfo requestInfo)