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.Iterator;
12  import java.util.Map;
13  import java.util.TreeMap;
14  
15  import org.apache.commons.logging.Log;
16  import org.apache.commons.logging.LogFactory;
17  
18  import gov.bnl.gums.GUMS;
19  import gov.bnl.gums.configuration.Configuration;
20  import gov.bnl.gums.db.AccountPoolMapperDB;
21  
22  /** 
23   * Provides the mapping by assigning user accounts from a pool provided by
24   * the AccountPoolMapperDB.
25   * <p>
26   * The accounts are mapped when the mapUser function is called for that
27   * particular user. Accounts are never deleted from the pool
28   *
29   * @todo should implement caching?
30   * @author  Gabriele Carcassi, Jay Packard
31   */
32  public class AccountPoolMapper extends AccountMapper {
33  	static public String getTypeStatic() {
34  		return "pool";
35  	}
36      
37  	private Log gumsResourceAdminLog = LogFactory.getLog(GUMS.resourceAdminLog);
38      private AccountPoolMapperDB db;
39      private String persistenceFactory = "";
40  	private String accountPool = "";
41  	private String assignmentString = "";
42  	private String assignments = "";
43      
44      public AccountPoolMapper() {
45      	super();
46      }
47   
48      public AccountPoolMapper(Configuration configuration) {
49      	super(configuration);
50      }
51      
52      public AccountPoolMapper(Configuration configuration, String name) {
53      	super(configuration, name);
54      }
55      
56      public AccountMapper clone(Configuration configuration) {
57      	AccountPoolMapper accountMapper = new AccountPoolMapper(configuration, new String(getName()));
58      	accountMapper.setDescription(new String(getDescription()));
59      	accountMapper.setAccountPool(new String(accountPool));
60      	accountMapper.setPersistenceFactory(new String(persistenceFactory));
61      	return accountMapper;
62      }
63      
64      public String getAccountPool() {
65      	return accountPool;
66      }
67      
68      public String getAccountPoolRoot() {
69      	int index = accountPool.indexOf(".");
70      	if (index != -1)
71      		return accountPool.substring(0, index);
72      	else
73      		return accountPool;
74      }
75  
76      public AccountPoolMapperDB getDB() {
77      	if (db==null)
78      		db = getConfiguration().getPersistenceFactory(persistenceFactory).retrieveAccountPoolMapperDB(accountPool);
79      	return db;
80      }    
81  
82      /**
83       * @return String representation of how many accounts are assigned in database for each root account
84       */
85      public String getAssignments() {
86  		if (getDB().needsCacheRefresh()) {
87  	    	String retStr = new String();
88  
89  	    	Map accountReverseMap = getDB().retrieveReverseAccountMap();
90  	    	TreeMap accountRoots = new TreeMap();
91  	    	Iterator it = accountReverseMap.keySet().iterator();
92  	    	while (it.hasNext()) {
93  	    		String account = (String)it.next();
94  	    		String accountRoot = getRoot(account);
95  	    		String accountNumber = getNumber(account);
96  	    		Object[] stats = (Object[])accountRoots.get(accountRoot);
97  	    		if (stats==null) {
98  	    			stats = new Object[3];
99  	    			stats[0] = new Integer(0); // total
100 	   				stats[1] = new Integer(0); // assigned
101 	   				stats[2] = new ArrayList(); // number list
102 	    		}
103     			stats[0] = new Integer(((Integer)stats[0]).intValue() + 1); // total
104     			if (!accountReverseMap.get(account).equals(""))
105     				stats[1] = new Integer(((Integer)stats[1]).intValue() + 1); // assigned
106    				((ArrayList)stats[2]).add(accountNumber); // number list
107 	    		accountRoots.put(accountRoot, stats);
108 	    	}
109 	    	it = accountRoots.keySet().iterator();
110 	    	while (it.hasNext()) {
111 	    		String accountRoot = (String)it.next();
112 	    		retStr += accountRoot;
113 	    		ArrayList numbers = (ArrayList)((Object[])accountRoots.get(accountRoot))[2];
114 	    		Collections.sort(numbers);
115 	    		Iterator numIt = numbers.iterator();
116 	    		String lastNumber = null;
117 	    		while(numIt.hasNext()) {
118 	    			String number = (String)numIt.next();
119 	    			if(lastNumber==null)
120     					retStr += number;
121 	    			else if(greaterThanOne(lastNumber, number))
122     					retStr += "-" + lastNumber + "," + number;
123 	    			else if(!numIt.hasNext())
124 	    				retStr += "-" + number;
125 	    			lastNumber = number;
126 	    		}
127 	    		retStr += "(" + 
128 	    			((Object[])accountRoots.get(accountRoot))[1] + "/" + 
129 	    			((Object[])accountRoots.get(accountRoot))[0] + ")";
130 	    		if (it.hasNext())
131 	    			retStr += ", ";
132 	    	}
133 	    	getDB().setNeedsCacheRefresh(false);
134 	    	assignments = retStr;
135 	    	return retStr;
136     	}
137 		else 
138 			return assignments;
139     }
140  
141     public String getPersistenceFactory() {
142        return persistenceFactory;
143     }
144         
145     public String getType() {
146 		return "pool";
147 	}
148     
149     public String mapUser(String userDN, boolean createIfDoesNotExist) {
150         String account = getDB().retrieveAccount(userDN);
151         if (account != null) return account;
152         if (createIfDoesNotExist) {
153         	String newAccount = getDB().assignAccount(userDN);
154         	if (newAccount==null)
155         		gumsResourceAdminLog.error("Could not assign user '"+userDN+"' to account within pool account mapper '"+getName()+"'.  The most likely cause is that there are no more available pool accounts, in which case you should add more.");
156         	return newAccount;
157         }
158         else
159         	return null;
160     }
161     
162     public void setAccountPool(String accountPool) {
163     	this.accountPool = accountPool;
164     }
165     
166     public void setPersistenceFactory(String persistenceFactory) {
167         this.persistenceFactory = persistenceFactory;
168     }
169 
170     public String toString(String bgColor) {
171     	return "<td bgcolor=\""+bgColor+"\"><a href=\"accountMappers.jsp?command=edit&name=" + getName() + "\">" + getName() + "</a></td><td bgcolor=\""+bgColor+"\">" + getType() + "</td><td bgcolor=\""+bgColor+"\">" + getAssignments() + "</td>";
172     }
173     
174     public String toXML() {
175     	return "\t\t<accountPoolMapper\n"+
176 			"\t\t\tname='"+getName()+"'\n"+
177 			"\t\t\tdescription='"+getDescription()+"'\n"+
178 			"\t\t\tpersistenceFactory='"+persistenceFactory+"'\n" +
179     		"\t\t\taccountPool='"+accountPool+"'/>\n\n";
180     }
181     
182     private static String getRoot(String account) {
183     	String upper = account.toUpperCase();
184     	String lower = account.toLowerCase();
185     	int i = 0, len = lower.length();
186     	while (i<len && lower.charAt(i)!=upper.charAt(i))
187     		i++;
188     	return new String( account.substring(0,i) );
189     }
190     
191     private static String getNumber(String account) {
192     	String upper = account.toUpperCase();
193     	String lower = account.toLowerCase();
194     	int i = 0, len = lower.length();
195     	while (i<len && lower.charAt(i)!=upper.charAt(i))
196     		i++;
197     	return new String( account.substring(i) );
198     }    
199     
200     private static boolean greaterThanOne(String smaller, String larger) {
201     	if (smaller.length() != larger.length())
202     		return true;
203     	int i1 = Integer.parseInt(smaller);
204     	int i2 = Integer.parseInt(larger);
205     	return (i2 > i1+1);
206     }
207 }