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