View Javadoc

1   /*
2    * ManualAccountMapper.java
3    *
4    * Created on May 25, 2004, 5:06 PM
5    */
6   
7   package gov.bnl.gums.account;
8   
9   import java.util.ArrayList;
10  import java.util.Date;
11  import java.util.HashMap;
12  import java.util.HashSet;
13  import java.util.List;
14  import java.util.Map;
15  import java.util.Set;
16  
17  import javax.persistence.CascadeType;
18  import javax.persistence.Entity;
19  import javax.persistence.OneToMany;
20  import javax.persistence.Transient;
21  
22  import gov.bnl.gums.Mapping;
23  import gov.bnl.gums.SiteUser;
24  import gov.bnl.gums.configuration.ConfigElement;
25  import gov.bnl.gums.configuration.Configuration;
26  import gov.bnl.gums.util.RWLock;
27  
28  /** 
29   * An account mapping policy that looks at a stored table to determine the
30   * account. The database implementation is an abstract interface, which
31   * allows the mapping to be persistent on different mediums (i.e. database,
32   * LDAP, file, ...)
33   * <p>
34   * This class will provide also configurable data caching.
35   *
36   * @author Gabriele Carcassi, Jay Packard
37   */
38  @Entity
39  public class ManualAccountMapper extends AccountMapper {
40      private Map<String, SiteUser> map = new HashMap<String, SiteUser>();
41      private Map<SiteUser, Set<String>> reverseMap = new HashMap<SiteUser, Set<String>>();
42  	protected RWLock patternRWLock = new RWLock();
43  
44  	// persistent variables
45  	protected Date lastUpdate;
46  	protected List<Mapping> mappings = new ArrayList<Mapping>();
47  	
48      public ManualAccountMapper() {
49      	super();
50      }
51      
52      public ManualAccountMapper(Configuration configuration, String name) {
53      	super(configuration, name);
54      }
55  	
56      public ConfigElement clone(Configuration conf, boolean allowReplace) {
57      	ManualAccountMapper manualAccountMapper = (ManualAccountMapper)super.clone(conf, allowReplace);
58      	manualAccountMapper.setMappings(new ArrayList<Mapping>(mappings));
59      	return manualAccountMapper;
60      }
61      
62  	public final void createMapping(String dn, SiteUser siteUser) {
63  		synchronized(mappings) {
64  			Mapping mapping = null;
65  			int index;
66  			if ((index = mappings.indexOf(siteUser)) != -1) {
67  				mapping = mappings.get(index);
68  				mapping.setDn(dn);
69  			}
70  			else {
71  				mapping = new Mapping(dn, siteUser);
72  				mappings.add(mapping);
73  			}
74  			mapping.setAccountMapper(this);
75  		}
76  		refreshMaps();
77  	}
78  	
79  	public Date getLastUpdate() {
80  		return lastUpdate;
81  	}
82  	
83  	@OneToMany(cascade=CascadeType.ALL, mappedBy="accountMapper") 
84  	@org.hibernate.annotations.Cascade(org.hibernate.annotations.CascadeType.DELETE_ORPHAN)
85  	public List<Mapping> getMappings() {
86  		return mappings;
87  	}
88      
89      public SiteUser mapDn(String dn, boolean createNew){
90  		if (dn == null)
91  			return null;
92      	try {
93  	    	patternRWLock.getReadLock();
94  			return map.get(dn);
95      	}
96      	finally {
97      		patternRWLock.releaseLock();
98      	}
99  	}
100     
101     public Set<String> mapSiteUser(SiteUser siteUser) {
102     	if (siteUser == null)
103 			return null;
104     	try {
105 	    	patternRWLock.getReadLock();
106 			return reverseMap.get(siteUser);
107     	}
108     	finally {
109     		patternRWLock.releaseLock();
110     	}
111     }
112 
113     public boolean removeMapping(String dn) {
114     	boolean retVal = false;
115     	assert(dn != null);
116     	synchronized(mappings) {
117 			for (Mapping m: mappings) {
118 				if (m.getDn().equals(dn)) {
119 					retVal = mappings.remove(m);
120 					break;
121 				}
122 			}
123     	}
124     	if (retVal)
125     		refreshMaps();
126     	return retVal;
127 	}
128     
129     public void removeMapping(SiteUser siteUser) {
130 		assert(siteUser != null);
131 		synchronized(mappings) {
132 			for (Mapping m: mappings) {
133 				if (m.getSiteUser().equals(siteUser)) {
134 					mappings.remove(m);
135 				}
136 			}
137 		}
138 		refreshMaps();
139 	}      
140 
141 	public void setLastUpdate(Date lastUpdate) {
142 		this.lastUpdate = lastUpdate;
143 	}
144 	
145 	
146 	protected void refreshMaps() {
147 		try {
148 	    	patternRWLock.getWriteLock();
149 	    	map.clear();
150 	    	reverseMap.clear();
151 			synchronized (mappings) {
152 				for (Mapping m: mappings) {
153 					if (m.getDn() != null) {
154 						map.put(m.getDn(), m.getSiteUser());
155 						Set<String> users = reverseMap.get(m.getSiteUser());
156 						if (users == null) {
157 							users = new HashSet<String>();
158 							users.add(m.getDn());
159 							reverseMap.put(m.getSiteUser(), users);
160 						}
161 					}
162 				}
163 			}
164     	}
165     	finally {
166     		patternRWLock.releaseLock();
167     	}
168 	}
169 
170 	private void setMappings(List<Mapping> mappings) {
171 		if (mappings == null || mappings.size()==0)
172 			return;
173 		this.mappings = mappings;
174     	for (Mapping m: mappings)
175     		m.setAccountMapper(this);
176 		refreshMaps();
177 	}
178    
179 }