View Javadoc
1   /**
2    * Copyright 2014 Internet2
3    *
4    * Licensed under the Apache License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    *
8    *   http://www.apache.org/licenses/LICENSE-2.0
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   */
16  /*--
17  $Id: BaseSourceAdapter.java,v 1.8 2009-10-30 20:41:41 mchyzer Exp $
18  $Date: 2009-10-30 20:41:41 $
19   
20  Copyright 2005 Internet2 and Stanford University.  All Rights Reserved.
21  See doc/license.txt in this distribution.
22   */
23  package edu.internet2.middleware.subject.provider;
24  
25  import java.util.Collection;
26  import java.util.HashMap;
27  import java.util.HashSet;
28  import java.util.LinkedHashMap;
29  import java.util.Map;
30  import java.util.Properties;
31  import java.util.Set;
32  
33  import org.apache.commons.collections.map.CaseInsensitiveMap;
34  import org.apache.commons.lang.StringUtils;
35  import org.apache.commons.logging.Log;
36  import org.apache.commons.logging.LogFactory;
37  
38  import edu.internet2.middleware.grouper.util.GrouperUtil;
39  import edu.internet2.middleware.grouperClient.util.GrouperClientUtils;
40  import edu.internet2.middleware.subject.SearchPageResult;
41  import edu.internet2.middleware.subject.Source;
42  import edu.internet2.middleware.subject.SourceUnavailableException;
43  import edu.internet2.middleware.subject.Subject;
44  import edu.internet2.middleware.subject.SubjectCaseInsensitiveMapImpl;
45  import edu.internet2.middleware.subject.SubjectCaseInsensitiveSetImpl;
46  import edu.internet2.middleware.subject.SubjectNotFoundException;
47  import edu.internet2.middleware.subject.SubjectNotUniqueException;
48  import edu.internet2.middleware.subject.SubjectType;
49  import edu.internet2.middleware.subject.SubjectUtils;
50  import edu.internet2.middleware.subject.config.SubjectConfig;
51  import edu.internet2.middleware.subject.provider.SourceManager.SourceManagerStatusBean;
52  
53  /**
54   * <pre>
55   * Base Source adapter.
56   * 
57   * Developers note: you should implement the getSubject and getSubjectByIdentifier
58   * methods (that take boolean) since the base class method will soon become abstract, and the
59   * method overloads which are deprecated and dont take booleans will go away.
60   * 
61   * </pre>
62   */
63  public abstract class BaseSourceAdapter implements Source {
64    
65    private Map<String, Void> sourceAttributesToLowerCase = null;
66    
67    protected String nameAttributeName;
68    protected String descriptionAttributeName;
69    
70    
71    protected Subject createSubject(Map<String, Object> sourceAttributesToValues, String subjectID) {
72      
73      Map<String, Object> translationMap = new CaseInsensitiveMap();
74      
75      for (String sourceAttribute: sourceAttributesToValues.keySet()) {
76        translationMap.put("source_attribute__"+sourceAttribute, sourceAttributesToValues.get(sourceAttribute));
77      }
78      
79      Map<String, Object> subjectAttributesToValues = new CaseInsensitiveMap();
80      
81      String numberOfAttributes = SubjectConfig.retrieveConfig().propertyValueString("subjectApi.source." + this.getConfigId() + ".numberOfAttributes");
82      
83      if (StringUtils.isNotBlank(numberOfAttributes)) {
84        
85        int numberOfAttrs = Integer.parseInt(numberOfAttributes);
86        for (int i=0; i<numberOfAttrs; i++) {
87          
88          String subjectAttributeName = SubjectConfig.retrieveConfig().propertyValueString("subjectApi.source." + this.getConfigId() + ".attribute."+i+".name");
89          
90          String translationType = SubjectConfig.retrieveConfig().propertyValueString("subjectApi.source." + this.getConfigId() + ".attribute."+i+".translationType");
91          
92          boolean isSourceAttribute = StringUtils.equals(translationType, "sourceAttribute");
93          boolean isSourceAttributeSameAsSubjectAttribute = StringUtils.equals(translationType, "sourceAttributeSameAsSubjectAttribute");
94          
95          if (isSourceAttributeSameAsSubjectAttribute) {
96            Object value = sourceAttributesToValues.get(subjectAttributeName);
97            subjectAttributesToValues.put(subjectAttributeName, value);
98            translationMap.put("subject_attribute__"+subjectAttributeName.toLowerCase(), value);
99          } else if (isSourceAttribute) {
100           
101           String sourceAttribute = SubjectConfig.retrieveConfig().propertyValueString("subjectApi.source." + this.getConfigId() + ".attribute."+i+".sourceAttribute").toLowerCase();
102 
103           Object value = sourceAttributesToValues.get(sourceAttribute);
104           subjectAttributesToValues.put(subjectAttributeName, value);
105           translationMap.put("subject_attribute__"+subjectAttributeName.toLowerCase(), value);
106         }
107         
108       }
109       
110       
111       for (int i=0; i<numberOfAttrs; i++) {
112         
113         String subjectAttributeName = SubjectConfig.retrieveConfig().propertyValueString("subjectApi.source." + this.getConfigId() + ".attribute."+i+".name");
114         
115         String translationType = SubjectConfig.retrieveConfig().propertyValueString("subjectApi.source." + this.getConfigId() + ".attribute."+i+".translationType");
116         
117         boolean isTranslation = StringUtils.equals(translationType, "translation");
118         
119         if (isTranslation) {
120 
121           String translation = SubjectConfig.retrieveConfig().propertyValueString("subjectApi.source." + this.getConfigId() + ".attribute."+i+".translation");
122           
123           Object valueObject = GrouperUtil.substituteExpressionLanguageScript(translation, translationMap, true, false, true);
124           valueObject = GrouperUtil.stringValue(valueObject);
125           subjectAttributesToValues.put(subjectAttributeName, valueObject);
126           
127         }
128         
129       }
130       
131     }
132           
133      
134     SubjectImplt/provider/SubjectImpl.html#SubjectImpl">SubjectImpl subject = new SubjectImpl(subjectID, null, null, this.getSubjectType().getName(), this.getId(), nameAttributeName, descriptionAttributeName);
135     subject.setTranslationMap(translationMap);
136     
137     // add the attributes
138     Map<String, Set<String>> myAttributes = new  SubjectCaseInsensitiveMapImpl<String, Set<String>>();
139 
140     for (String subjectAttributeName: subjectAttributesToValues.keySet()) {
141       Object value = subjectAttributesToValues.get(subjectAttributeName);
142       if (value instanceof Set) {
143         myAttributes.put(subjectAttributeName, (Set<String>)value);
144       } else {
145         myAttributes.put(subjectAttributeName, GrouperUtil.toSetObject((String)value));
146       }
147     }
148 
149     subject.setAttributes(myAttributes);
150     return subject;
151   }
152   
153   public Map<String, Void> getSourceAttributesToLowerCase() {
154     
155     if (sourceAttributesToLowerCase == null) {
156       
157       Map<String, Void> temp = new CaseInsensitiveMap();
158       
159       String numberOfAttributes = SubjectConfig.retrieveConfig().propertyValueString("subjectApi.source." + this.getConfigId() + ".numberOfAttributes");
160             
161       if (StringUtils.isNotBlank(numberOfAttributes)) {
162         
163         int numberOfAttrs = Integer.parseInt(numberOfAttributes);
164         for (int i=0; i<numberOfAttrs; i++) {
165                     
166           boolean formatToLowerCase = SubjectConfig.retrieveConfig().propertyValueBoolean("subjectApi.source." + this.getConfigId() + ".attribute."+i+".formatToLowerCase", false);
167           
168           String translationType = SubjectConfig.retrieveConfig().propertyValueString("subjectApi.source." + this.getConfigId() + ".attribute."+i+".translationType");
169           
170           boolean isSourceAttribute = StringUtils.equals(translationType, "sourceAttribute");
171           boolean isSourceAttributeSameAsSubjectAttribute = StringUtils.equals(translationType, "sourceAttributeSameAsSubjectAttribute");
172           
173           if (formatToLowerCase) {
174             if (isSourceAttributeSameAsSubjectAttribute) {
175               String subjectAttributeName = SubjectConfig.retrieveConfig().propertyValueString("subjectApi.source." + this.getConfigId() + ".attribute."+i+".name");
176               temp.put(subjectAttributeName, null);
177             } else if (isSourceAttribute) {
178               String sourceAttribute = SubjectConfig.retrieveConfig().propertyValueString("subjectApi.source." + this.getConfigId() + ".attribute."+i+".sourceAttribute");
179               temp.put(sourceAttribute, null);
180             }
181             
182           } 
183        
184         }
185         
186       }
187             
188       sourceAttributesToLowerCase = temp;
189       
190     }
191     
192     return sourceAttributesToLowerCase;
193   }
194 
195 
196   public String convertSubjectAttributeToSourceAttribute(String nameOfSubjectAttribute) {
197     
198     String numberOfAttributes = SubjectConfig.retrieveConfig().propertyValueString("subjectApi.source." + this.getConfigId() + ".numberOfAttributes");
199     
200     if (this.isEditable()) {
201           
202       if (StringUtils.isNotBlank(numberOfAttributes)) {
203         
204         int numberOfAttrs = Integer.parseInt(numberOfAttributes);
205         for (int i=0; i<numberOfAttrs; i++) {
206           
207           String subjectAttributeName = SubjectConfig.retrieveConfig().propertyValueString("subjectApi.source." + this.getConfigId() + ".attribute."+i+".name");
208           
209           String translationType = SubjectConfig.retrieveConfig().propertyValueString("subjectApi.source." + this.getConfigId() + ".attribute."+i+".translationType");
210           
211           boolean isSourceAttribute = StringUtils.equals(translationType, "sourceAttribute");
212           
213           String sourceAttribute = SubjectConfig.retrieveConfig().propertyValueString("subjectApi.source." + this.getConfigId() + ".attribute."+i+".sourceAttribute");
214           if (StringUtils.equals(nameOfSubjectAttribute, subjectAttributeName)) {
215             if (isSourceAttribute) {
216               return sourceAttribute;
217             }
218           }
219         }
220         
221       }
222           
223     }
224     
225     return nameOfSubjectAttribute;
226     
227   } 
228   
229   
230   public String convertSourceAttributeToSubjectAttribute(String nameOfSourceAttribute) {
231     
232     String numberOfAttributes = SubjectConfig.retrieveConfig().propertyValueString("subjectApi.source." + this.getConfigId() + ".numberOfAttributes");
233     
234     if (this.isEditable()) {
235           
236       if (StringUtils.isNotBlank(numberOfAttributes)) {
237         
238         int numberOfAttrs = Integer.parseInt(numberOfAttributes);
239         for (int i=0; i<numberOfAttrs; i++) {
240           
241           String sourceAttribute = SubjectConfig.retrieveConfig().propertyValueString("subjectApi.source." + this.getConfigId() + ".attribute."+i+".sourceAttribute");
242           if (StringUtils.equals(nameOfSourceAttribute, sourceAttribute)) {
243             
244             String translationType = SubjectConfig.retrieveConfig().propertyValueString("subjectApi.source." + this.getConfigId() + ".attribute."+i+".translationType");
245             
246             boolean isSourceAttribute = StringUtils.equals(translationType, "sourceAttribute");
247             
248             if (isSourceAttribute) {
249               return SubjectConfig.retrieveConfig().propertyValueString("subjectApi.source." + this.getConfigId() + ".attribute."+i+".name");
250             }
251           }
252         }
253         
254       }
255           
256     }
257     
258     return nameOfSourceAttribute;
259     
260   } 
261   
262   
263   /**
264    * @see edu.internet2.middleware.subject.Source#retrieveAllSubjectIds()
265    */
266   @Override
267   public Set<String> retrieveAllSubjectIds() {
268     throw new UnsupportedOperationException();
269   }
270 
271 
272   /**
273    * @see edu.internet2.middleware.subject.Source#getSubject(java.lang.String, boolean, java.lang.String)
274    */
275   @Override
276   public Subject getSubject(String id1, boolean exceptionIfNull, String realm)
277       throws SubjectNotFoundException, SubjectNotUniqueException {
278     return this.getSubject(id1, exceptionIfNull);
279   }
280 
281 
282   /**
283    * @see edu.internet2.middleware.subject.Source#getSubjectByIdentifier(java.lang.String, boolean, java.lang.String)
284    */
285   @Override
286   public Subject getSubjectByIdentifier(String id1, boolean exceptionIfNull, String realm)
287       throws SubjectNotFoundException, SubjectNotUniqueException {
288     return this.getSubjectByIdentifier(id1, exceptionIfNull);
289   }
290 
291 
292   /**
293    * @see edu.internet2.middleware.subject.Source#getSubjectByIdOrIdentifier(java.lang.String, boolean, java.lang.String)
294    */
295   @Override
296   public Subject getSubjectByIdOrIdentifier(String idOrIdentifier,
297       boolean exceptionIfNull, String realm) throws SubjectNotFoundException,
298       SubjectNotUniqueException {
299     return this.getSubjectByIdOrIdentifier(idOrIdentifier, exceptionIfNull);
300   }
301 
302 
303   /**
304    * @see edu.internet2.middleware.subject.Source#getSubjectsByIdentifiers(java.util.Collection, java.lang.String)
305    */
306   @Override
307   public Map<String, Subject> getSubjectsByIdentifiers(Collection<String> identifiers,
308       String realm) {
309     return this.getSubjectsByIdentifiers(identifiers);
310   }
311 
312 
313   /**
314    * @see edu.internet2.middleware.subject.Source#getSubjectsByIds(java.util.Collection, java.lang.String)
315    */
316   @Override
317   public Map<String, Subject> getSubjectsByIds(Collection<String> ids, String realm) {
318     return this.getSubjectsByIds(ids);
319   }
320 
321 
322   /**
323    * @see edu.internet2.middleware.subject.Source#getSubjectsByIdsOrIdentifiers(java.util.Collection, java.lang.String)
324    */
325   @Override
326   public Map<String, Subject> getSubjectsByIdsOrIdentifiers(
327       Collection<String> idsOrIdentifiers, String realm) {
328     return null;
329   }
330 
331 
332   /**
333    * @see edu.internet2.middleware.subject.Source#search(java.lang.String, java.lang.String)
334    */
335   @Override
336   public Set<Subject> search(String searchValue, String realm) {
337     return this.search(searchValue);
338   }
339 
340 
341   /**
342    * @see edu.internet2.middleware.subject.Source#searchPage(java.lang.String, java.lang.String)
343    */
344   @Override
345   public SearchPageResult searchPage(String searchValue, String realm) {
346     return this.searchPage(searchValue);
347   }
348 
349 
350   /**
351    * @see Source#getSubjectStatusConfig()
352    */
353   @Override
354   public SubjectStatusConfig getSubjectStatusConfig() {
355 
356     //get the cached config for this source
357     SourceManager sourceManager = SourceManager.getInstance();
358     SourceManagerStatusBean sourceManagerStatusBean = sourceManager.getSourceManagerStatusBean();
359     Map<String, SubjectStatusConfig> sourceIdToStatusConfigs = sourceManagerStatusBean.getSourceIdToStatusConfigs();
360 
361 //    System.out.println(sourceManager.hashCode() + ", " 
362 //        + sourceManagerStatusBean.hashCode() + ", " 
363 //        + sourceIdToStatusConfigs.hashCode() + ", " 
364 //        + sourceIdToStatusConfigs.size() + ", " 
365 //        + sourceIdToStatusConfigs.get("g:gsa") + ", " + this.getId());
366     
367     return sourceIdToStatusConfigs.get(this.getId());
368     
369   }
370 
371 
372   /**
373    * see what the result set limit should be (dont add one yet)
374    * @param firstPageOnly
375    * @param pageSize
376    * @param theMaxResults
377    * @return the limit or null if none
378    */
379   public static Integer resultSetLimit(boolean firstPageOnly, Integer pageSize, Integer theMaxResults) {
380     Integer result = null;
381     if ((firstPageOnly && pageSize != null) || theMaxResults != null) {
382       result = (firstPageOnly && pageSize != null) ? (pageSize) : null;
383       if (result == null) {
384         result = theMaxResults;
385       } else if (theMaxResults != null){
386         result = Math.min(result, theMaxResults);
387       }
388     }
389     return result;
390   }
391   
392 
393   /**
394    * @see edu.internet2.middleware.subject.Source#searchPage(java.lang.String)
395    */
396   public SearchPageResult searchPage(String searchValue) {
397     Set<Subject> results = this.search(searchValue);
398     return new SearchPageResult(false, results);
399   }
400 
401   /**
402    * @see edu.internet2.middleware.subject.Source#getSubjectsByIdentifiers(java.util.Collection)
403    */
404   public Map<String, Subject> getSubjectsByIdentifiers(Collection<String> identifiers) {
405     Map<String, Subject> result = new LinkedHashMap<String, Subject>();
406     
407     Subject subject = null;
408     for (String theIdentifier : identifiers) {
409       if (theIdentifier == null ) {
410         continue;
411       }
412 
413       try {
414         subject = getSubjectByIdentifier(theIdentifier, true);
415         result.put(theIdentifier, subject);
416       } catch (SubjectNotFoundException snfe) {
417         //ignore
418       } catch (SubjectNotUniqueException snue) {
419         //ignore
420       }
421     }
422     return result;
423   }
424 
425   /**
426    * @see edu.internet2.middleware.subject.Source#getSubjectsByIds(java.util.Collection)
427    */
428   public Map<String, Subject> getSubjectsByIds(Collection<String> ids) {
429     Map<String, Subject> result = new LinkedHashMap<String, Subject>();
430     
431     Subject subject = null;
432     for (String theId : SubjectUtils.nonNull(ids)) {
433       try {
434         subject = getSubject(theId, true);
435         result.put(theId, subject);
436       } catch (SubjectNotFoundException snfe) {
437         //ignore
438       } catch (SubjectNotUniqueException snue) {
439         //ignore
440       }
441     }
442     return result;
443     
444   }
445   
446   /**
447    * find by id or identifier
448    * @param idOrIdentifier
449    * @param exceptionIfNull if SubjectNotFoundException or null
450    * @return the subject
451    * @throws SubjectNotFoundException 
452    * @throws SubjectNotUniqueException 
453    */
454   public Subject getSubjectByIdOrIdentifier(String idOrIdentifier, boolean exceptionIfNull) 
455       throws SubjectNotFoundException, SubjectNotUniqueException {
456     
457     Map<String, Object> debugLog = null;
458     try {
459       if (log.isDebugEnabled()) {
460         debugLog = new LinkedHashMap<String, Object>();
461         debugLog.put("method", "getSubjectByIdOrIdentifier");
462         debugLog.put("idOrIdentifier", idOrIdentifier);
463         debugLog.put("exceptionIfNull", exceptionIfNull);
464       }
465       
466       Subject subject = null;
467   
468       //try by id first
469       subject = this.getSubject(idOrIdentifier, false);
470   
471       //try by identifier if not by id
472       if (subject == null) {
473         if (debugLog != null) {
474           debugLog.put("subjectById", "notFound");
475         }
476         subject = this.getSubjectByIdentifier(idOrIdentifier, false);
477         if (debugLog != null) {
478           debugLog.put("subjectByIdentifier", subject == null ? "notFound" : "found");
479         }
480       } else {
481         if (debugLog != null) {
482           debugLog.put("subjectById", "found");
483         }
484       }
485   
486       //if null at this point, and exception, then throw it
487       if (subject == null && exceptionIfNull) {
488         throw new SubjectNotFoundException("Cant find subject by id or identifier: '" + idOrIdentifier + "'"); 
489       }
490   
491       return subject;
492     } finally {
493       if (log.isDebugEnabled()) {
494         log.debug(SubjectUtils.mapToString(debugLog));
495       }
496     }
497   }
498   
499   /**
500    * @see edu.internet2.middleware.subject.Source#getSubjectsByIdsOrIdentifiers(java.util.Collection)
501    */
502   public Map<String, Subject> getSubjectsByIdsOrIdentifiers(
503       Collection<String> idsOrIdentifiers) {
504     Map<String, Subject> result = new LinkedHashMap<String, Subject>();
505 
506     if (SubjectUtils.length(idsOrIdentifiers) == 0) {
507       return result;
508     }
509     //do these in batches so they have the batched performance...
510     result.putAll(SubjectUtils.nonNull(this.getSubjectsByIdentifiers(idsOrIdentifiers)));
511     
512     //take out the ones that were found
513     Set<String> identifiers = new HashSet<String>(idsOrIdentifiers);
514     identifiers.removeAll(result.keySet());
515     if (SubjectUtils.length(identifiers) > 0) {
516       result.putAll(SubjectUtils.nonNull(this.getSubjectsByIds(identifiers)));
517     }
518     
519     return result;
520   }
521 
522   /**
523    * 
524    */
525   private static Log log = LogFactory.getLog(BaseSourceAdapter.class);
526 
527   /** */
528   protected String id = null;
529 
530   /** */
531   protected String name = null;
532 
533   /** */
534   protected Set<SubjectType> types = new HashSet<SubjectType>();
535 
536   /** */
537   protected SubjectType type = null;
538 
539   /** */
540   protected Properties params = new Properties();
541 
542   /** The three different kinds of searches:  */
543   protected HashMap<String, Search> searches = new HashMap<String, Search>();
544 
545   /** */
546   protected Set<String> attributes = new SubjectCaseInsensitiveSetImpl<String>();
547 
548   /** internal attributes. */
549   protected Set<String> internalAttributes = new SubjectCaseInsensitiveSetImpl<String>();
550   
551   protected Map<Integer, String> subjectIdentifierAttributes = null;
552   
553   protected Map<Integer, String> subjectIdentifierAttributesAll = null;
554   
555   protected Map<Integer, String> sortAttributes = null;
556   
557   protected Map<Integer, String> searchAttributes = null;
558   /**
559    * Default constructor.
560    */
561   public BaseSourceAdapter() {
562   }
563 
564   /**
565    * Allocates adapter with ID and name.
566    * @param id1
567    * @param name1
568    */
569   public BaseSourceAdapter(String id1, String name1) {
570     this.id = id1;
571     this.name = name1;
572   }
573 
574   /**
575    * {@inheritDoc}
576    */
577   public String getId() {
578     return this.id;
579   }
580 
581   /**
582    * {@inheritDoc}
583    */
584   public void setId(String id1) {
585     this.id = id1;
586   }
587 
588   /**
589    * {@inheritDoc}
590    */
591   public String getName() {
592     return this.name;
593   }
594 
595   /**
596    * {@inheritDoc}
597    */
598   public void setName(String name1) {
599     this.name = name1;
600   }
601 
602   /**
603    * {@inheritDoc}
604    */
605   public Set<SubjectType> getSubjectTypes() {
606     return this.types;
607   }
608 
609   /**
610    * 
611    * @return subject type
612    */
613   public SubjectType getSubjectType() {
614     return this.type;
615   }
616 
617   /**
618    * 
619    * @see edu.internet2.middleware.subject.Source#getSubject(java.lang.String)
620    * @deprecated use the overload instead
621    */
622   @Deprecated
623   public abstract Subject getSubject(String id1) throws SubjectNotFoundException,
624       SubjectNotUniqueException;
625 
626   /**
627    * 
628    * @see edu.internet2.middleware.subject.Source#getSubject(java.lang.String, boolean)
629    */
630   public Subject getSubject(String id1, boolean exceptionIfNull)
631       throws SubjectNotFoundException, SubjectNotUniqueException {
632     //NOTE this implementation is here temporarily for backwards compatibility... it will go away soon
633     //and this method will become abstract
634     try {
635       return this.getSubject(id1);
636     } catch (SubjectNotFoundException snfe) {
637       if (exceptionIfNull) {
638         throw snfe;
639       }
640       return null;
641     }
642 
643   }
644 
645   /**
646    * 
647    * @see edu.internet2.middleware.subject.Source#getSubjectByIdentifier(java.lang.String)
648    * @deprecated use the overload instead
649    */
650   @Deprecated
651   public abstract Subject getSubjectByIdentifier(String id1)
652       throws SubjectNotFoundException, SubjectNotUniqueException;
653 
654   /**
655    * note, you should implement this method since this implementation will become abstract at some point
656    * @see edu.internet2.middleware.subject.Source#getSubjectByIdentifier(java.lang.String, boolean)
657    */
658   public Subject getSubjectByIdentifier(String id1, boolean exceptionIfNull)
659       throws SubjectNotFoundException, SubjectNotUniqueException {
660     //NOTE this implementation is here temporarily for backwards compatibility... it will go away soon
661     //and this method will become abstract
662     try {
663       return this.getSubjectByIdentifier(id1);
664     } catch (SubjectNotFoundException snfe) {
665       if (exceptionIfNull) {
666         throw snfe;
667       }
668       return null;
669     }
670   }
671 
672   /**
673    * {@inheritDoc}
674    */
675   @SuppressWarnings("unchecked")
676   public abstract Set<Subject> search(String searchValue);
677 
678   /**
679    * {@inheritDoc}
680    */
681   public abstract void init() throws SourceUnavailableException;
682 
683   /**
684    * Compares this source against the specified source.
685    * Returns true if the IDs of both sources are equal.
686    */
687   @Override
688   public boolean equals(Object other) {
689     if (this == other) {
690       return true;
691     }
692     if (other instanceof BaseSourceAdapter) {
693       return this.getId().equals(((BaseSourceAdapter) other).getId());
694     }
695     return false;
696   }
697 
698   /**
699    * @see java.lang.Object#hashCode()
700    */
701   @Override
702   public int hashCode() {
703     return "BaseSourceAdapter".hashCode() + this.getId().hashCode();
704   }
705 
706   /**
707    * (non-javadoc)
708    * @param type1
709    */
710   public void addSubjectType(String type1) {
711     this.types.add(SubjectTypeEnum.valueOf(type1));
712     this.type = SubjectTypeEnum.valueOf(type1);
713   }
714 
715   /**
716    * (non-javadoc)
717    * @param name1
718    * @param value
719    */
720   public void addInitParam(String name1, String value) {
721     this.params.setProperty(name1, GrouperClientUtils.defaultString(value));
722   }
723   
724   /**
725    * @param name1
726    */
727   public void removeInitParam(String name1) {
728     this.params.remove(name1);
729   }
730 
731   /**
732    * (non-javadoc)
733    * @param name1
734    * @return param
735    */
736   public String getInitParam(String name1) {
737     return this.params.getProperty(name1);
738   }
739 
740   /**
741    * (non-javadoc)
742    * @return params
743    */
744   public Properties initParams() {
745     return this.params;
746   }
747 
748   /**
749    * 
750    * @param attributeName
751    */
752   public void addAttribute(String attributeName) {
753     this.attributes.add(attributeName);
754   }
755   
756   /**
757    * @param attributeName
758    */
759   public void addInternalAttribute(String attributeName) {
760     this.internalAttributes.add(attributeName);
761   }
762 
763   /**
764    * 
765    * @return set
766    */
767   protected Set getAttributes() {
768     return this.attributes;
769   }
770   
771   /**
772    * @return set
773    */
774   public Set<String> getInternalAttributes() {
775     return this.internalAttributes;
776   }
777 
778   /**
779    * 
780    * @param searches1
781    */
782   protected void setSearches(HashMap<String, Search> searches1) {
783     this.searches = searches1;
784   }
785 
786   /**
787    * 
788    * @return map
789    */
790   protected HashMap<String, Search> getSearches() {
791     return this.searches;
792   }
793 
794   /**
795    * 
796    * @param searchType
797    * @return search
798    */
799   protected Search getSearch(String searchType) {
800     HashMap searches1 = getSearches();
801     return (Search) searches1.get(searchType);
802   }
803 
804   /**
805    * 
806    * @param search
807    */
808   public void loadSearch(Search search) {
809     if (log.isDebugEnabled()) {
810       log.debug("Loading search: " + (search == null ? null : search.getSearchType()));
811     }
812     this.searches.put(search.getSearchType(), search);
813   }
814   
815   /**
816    * @param subjectIdentifierAttributes
817    */
818   public void setSubjectIdentifierAttributes(Map<Integer, String> subjectIdentifierAttributes) {
819     this.subjectIdentifierAttributes = subjectIdentifierAttributes;
820   }
821   
822   /**
823    * @param sortAttributes
824    */
825   public void setSortAttributes(Map<Integer, String> sortAttributes) {
826     this.sortAttributes = sortAttributes;
827   }
828   
829   /**
830    * @param searchAttributes
831    */
832   public void setSearchAttributes(Map<Integer, String> searchAttributes) {
833     this.searchAttributes = searchAttributes;
834   }
835   
836   /**
837    * @see edu.internet2.middleware.subject.Source#getSubjectIdentifierAttributes()
838    */
839   public Map<Integer, String> getSubjectIdentifierAttributes() {
840     
841     if (this.subjectIdentifierAttributes == null) {
842       synchronized(BaseSourceAdapter.class) {
843         if (this.subjectIdentifierAttributes == null) {
844           LinkedHashMap<Integer, String> temp = new LinkedHashMap<Integer, String>();
845           
846           for (int i = 0; i < 1; i++) {
847             String value = getInitParam("subjectIdentifierAttribute" + i);
848             if (value != null) {
849               temp.put(i, value.toLowerCase());
850             }        
851           }
852           
853           String numberOfAttributes = SubjectConfig.retrieveConfig().propertyValueString("subjectApi.source." + this.getConfigId() + ".numberOfAttributes");
854           if (StringUtils.isNotBlank(numberOfAttributes)) {
855             
856             int numberOfAttrs = Integer.parseInt(numberOfAttributes);
857             for (int i=0; i<numberOfAttrs; i++) {
858               
859               boolean subjectIdentifier = SubjectConfig.retrieveConfig().propertyValueBoolean("subjectApi.source." + this.getConfigId() + ".attribute."+i+".subjectIdentifier", false);
860               if (subjectIdentifier) {
861                 String name = SubjectConfig.retrieveConfig().propertyValueString("subjectApi.source." + this.getConfigId() + ".attribute."+i+".name");
862                 if (StringUtils.isNotBlank(name)) {
863                   temp.put(temp.size()-1, name.toLowerCase());
864                 }
865               }
866             
867             }
868             
869           }
870           
871           this.subjectIdentifierAttributes = temp;
872         }
873       }
874     }
875     
876     
877     
878     return this.subjectIdentifierAttributes;
879   }
880   
881   /**
882    * @see edu.internet2.middleware.subject.Source#getSubjectIdentifierAttributesAll()
883    */
884   public Map<Integer, String> getSubjectIdentifierAttributesAll() {
885     
886     if (this.subjectIdentifierAttributesAll == null) {
887       synchronized(BaseSourceAdapter.class) {
888         if (this.subjectIdentifierAttributesAll == null) {
889           LinkedHashMap<Integer, String> temp = new LinkedHashMap<Integer, String>();
890           
891           for (int i = 0; i < 20; i++) {
892             String value = getInitParam("subjectIdentifierAttribute" + i);
893             if (value != null) {
894               temp.put(i, value.toLowerCase());
895             }  else {
896               break;
897             }
898           }
899           
900           String numberOfAttributes = SubjectConfig.retrieveConfig().propertyValueString("subjectApi.source." + this.getConfigId() + ".numberOfAttributes");
901           if (StringUtils.isNotBlank(numberOfAttributes)) {
902             
903             int numberOfAttrs = Integer.parseInt(numberOfAttributes);
904             for (int i=0; i<numberOfAttrs; i++) {
905               
906               boolean subjectIdentifier = SubjectConfig.retrieveConfig().propertyValueBoolean("subjectApi.source." + this.getConfigId() + ".attribute."+i+".subjectIdentifier", false);
907               if (subjectIdentifier) {
908                 String name = SubjectConfig.retrieveConfig().propertyValueString("subjectApi.source." + this.getConfigId() + ".attribute."+i+".name");
909                 if (StringUtils.isNotBlank(name)) {
910                   temp.put(temp.size()-1, name.toLowerCase());
911                 }
912               }
913             
914             }
915             
916           }
917           
918           this.subjectIdentifierAttributesAll = temp;
919         }
920       }
921     }
922     
923     return this.subjectIdentifierAttributesAll;
924   }
925   
926   /**
927    * @see edu.internet2.middleware.subject.Source#getSortAttributes()
928    */
929   public Map<Integer, String> getSortAttributes() {
930     
931     if (this.sortAttributes == null) {
932       synchronized(BaseSourceAdapter.class) {
933         if (this.sortAttributes == null) {
934           LinkedHashMap<Integer, String> temp = new LinkedHashMap<Integer, String>();
935           
936           for (int i = 0; i < 5; i++) {
937             String value = getInitParam("sortAttribute" + i);
938             if (value != null) {
939               temp.put(i, value.toLowerCase());
940             }        
941           }
942           
943           this.sortAttributes = temp;
944         }
945       }
946     }
947     
948     return this.sortAttributes;
949   }
950   
951   /**
952    * @see edu.internet2.middleware.subject.Source#getSearchAttributes()
953    */
954   public Map<Integer, String> getSearchAttributes() {
955     
956     if (this.searchAttributes == null) {
957       synchronized(BaseSourceAdapter.class) {
958         if (this.searchAttributes == null) {
959           LinkedHashMap<Integer, String> temp = new LinkedHashMap<Integer, String>();
960           
961           for (int i = 0; i < 5; i++) {
962             String value = getInitParam("searchAttribute" + i);
963             if (value != null) {
964               temp.put(i, value.toLowerCase());
965             }        
966           }
967           
968           this.searchAttributes = temp;
969         }
970       }
971     }
972     
973     return this.searchAttributes;
974   }
975 
976 
977   @Override
978   public boolean isEditable() {
979     return false;
980   }
981 
982   private String configId;
983   
984   @Override
985   public String getConfigId() {
986     return this.configId;
987   }
988   
989   @Override
990   public void setConfigId(String configId) {
991     this.configId = configId;
992   }
993 
994 
995   @Override
996   public boolean isEnabled() {
997     return true;
998   }
999   
1000 }