View Javadoc

1   /*
2    * AccountPoolMapper.java
3    *
4    * Created on June 16, 2004, 3:10 PM
5    */
6   
7   package gov.bnl.gums.account;
8   
9   import java.util.ArrayList;
10  import java.util.Collections;
11  import java.util.Date;
12  import java.util.HashSet;
13  import java.util.Iterator;
14  import java.util.Set;
15  import java.util.StringTokenizer;
16  import java.util.TreeMap;
17  
18  import gov.bnl.gums.Mapping;
19  import gov.bnl.gums.SiteUser;
20  import gov.bnl.gums.configuration.Configuration;
21  
22  import javax.persistence.*;
23  
24  /** 
25   * Provides the mapping by assigning user accounts from a pool provided by
26   * the AccountPoolMapperDB.
27   * <p>
28   * The accounts are mapped when the mapUser function is called for that
29   * particular user. Accounts are never deleted from the pool
30   *
31   * @author  Gabriele Carcassi, Jay Packard
32   */
33  @Entity
34  public class AccountPoolMapper extends ManualAccountMapper {
35  	protected String assignments = null;
36  	protected String pool;
37  	protected String primaryGroup;
38  	protected Set<String> secondaryGroups = new HashSet<String>();
39  
40  	// persistent fields
41  	protected String accountPool;
42  	
43      public AccountPoolMapper() {
44      	super();
45      }
46      
47      public AccountPoolMapper(Configuration configuration, String name) {
48      	super(configuration, name);
49      }
50      
51      public String getAccountPool() {
52      	return accountPool;
53      }
54      
55      @Transient
56      public String getAccountPoolRoot() {
57      	int index = accountPool.indexOf(".");
58      	if (index != -1)
59      		return accountPool.substring(0, index);
60      	else
61      		return accountPool;
62      } 
63  
64      /**
65       * @return String representation of how many accounts are assigned in database for each root account
66       */
67      @SuppressWarnings("unchecked")
68      @Transient
69  	public String getAssignments() {
70  		if (assignments==null || getLastUpdate().after(new Date())) {
71  	    	String retStr = new String();
72  
73  	    	TreeMap<String, Object> accountRoots = new TreeMap<String, Object>();
74  	    	Iterator<Mapping> it = mappings.iterator();
75  	    	while (it.hasNext()) {
76  	    		String account = it.next().getSiteUser().getAccount();
77  	    		String accountRoot = getRoot(account);
78  	    		String accountNumber = getNumber(account);
79  	    		Object[] stats = (Object[])accountRoots.get(accountRoot);
80  	    		if (stats==null) {
81  	    			stats = new Object[3];
82  	    			stats[0] = new Integer(0); // total
83  	   				stats[1] = new Integer(0); // assigned
84  	   				stats[2] = new ArrayList<String>(); // number list
85  	    		}
86      			stats[0] = new Integer(((Integer)stats[0]).intValue() + 1); // total
87      			if (mapSiteUser(new SiteUser(account)).size() != 0)
88      				stats[1] = new Integer(((Integer)stats[1]).intValue() + 1); // assigned
89     				((ArrayList<String>)stats[2]).add(accountNumber); // number list
90  	    		accountRoots.put(accountRoot, stats);
91  	    	}
92  	    	Iterator<String> rootIt = accountRoots.keySet().iterator();
93  	    	while (rootIt.hasNext()) {
94  	    		String accountRoot = rootIt.next();
95  	    		retStr += accountRoot;
96  	    		ArrayList<String> numbers = (ArrayList<String>)((Object[])accountRoots.get(accountRoot))[2];
97  	    		Collections.sort(numbers);
98  	    		Iterator<String> numIt = numbers.iterator();
99  	    		String lastNumber = null;
100 	    		while(numIt.hasNext()) {
101 	    			String number = (String)numIt.next();
102 	    			if(lastNumber==null)
103     					retStr += number;
104 	    			else if(greaterThanOne(lastNumber, number))
105     					retStr += "-" + lastNumber + "," + number;
106 	    			else if(!numIt.hasNext())
107 	    				retStr += "-" + number;
108 	    			lastNumber = number;
109 	    		}
110 	    		retStr += "(" + 
111 	    			((Object[])accountRoots.get(accountRoot))[1] + "/" + 
112 	    			((Object[])accountRoots.get(accountRoot))[0] + ")";
113 	    		if (it.hasNext())
114 	    			retStr += ", ";
115 	    	}
116 	    	assignments = retStr;
117 	    	return retStr;
118     	}
119 		else {
120 			return assignments;
121 		}
122     }
123 
124 	public SiteUser mapDn(String dn, boolean createNew){
125 		SiteUser siteUser = super.mapDn(dn, createNew);
126 		synchronized(mappings) {
127 			if (siteUser == null && createNew) {
128 				for (Mapping m: mappings) {
129 					if (m.getDn() == null) {
130 						m.setDn(dn);
131 						siteUser = m.getSiteUser();
132 						refreshMaps();
133 						break;
134 					}
135 				}
136 			}
137 		}
138 		return siteUser;
139 	}
140 	
141 	@ConfigFieldAnnotation(label="Pool Name / Groups", example="myPool.myPrimaryGroup.mySecondaryGroup1.mySecondaryGroup2... ")
142     public void setAccountPool(String accountPool) {
143     	this.accountPool = accountPool;
144 
145     	if (accountPool!=null) {
146 	    	StringTokenizer tokens = new StringTokenizer(accountPool, ".");
147 	    	pool = tokens.nextToken();
148 	    	if (tokens.hasMoreTokens())
149 	    		primaryGroup = tokens.nextToken();
150 	        while (tokens.hasMoreTokens())
151 	        	secondaryGroups.add(tokens.nextToken());
152     	}
153     }
154     
155     public void setLastUpdate(Date lastUpdate) {
156 		this.lastUpdate = lastUpdate;
157 	}    
158     
159     protected String getNumber(String account) {
160     	int i = account.length()-1;
161     	while (i>=0 && account.charAt(i)>=48 && account.charAt(i)<=57)
162     		i--;
163     	i++;
164     	return new String( account.substring(i) );
165     }
166 
167     protected String getRoot(String account) {
168     	int i = account.length()-1;
169     	while (i>=0 && account.charAt(i)>=48 && account.charAt(i)<=57)
170     		i--;
171     	i++;
172     	return new String( account.substring(0,i) );
173     }
174 
175 	protected boolean greaterThanOne(String smaller, String larger) {
176     	if (smaller.length() != larger.length())
177     		return true;
178     	int i1 = Integer.parseInt(smaller);
179     	int i2 = Integer.parseInt(larger);
180     	return (i2 > i1+1);
181     }
182 	
183 }