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   * @author mchyzer
18   * $Id: AuditTypeFinder.java,v 1.4 2009-05-13 12:15:01 mchyzer Exp $
19   */
20  package edu.internet2.middleware.grouper.audit;
21  
22  import java.util.HashMap;
23  import java.util.Map;
24  import java.util.Set;
25  
26  import edu.internet2.middleware.grouperClient.collections.MultiKey;
27  
28  import edu.internet2.middleware.grouper.GroupType;
29  import edu.internet2.middleware.grouper.cache.GrouperCache;
30  import edu.internet2.middleware.grouper.misc.GrouperDAOFactory;
31  import edu.internet2.middleware.grouper.util.GrouperUtil;
32  
33  
34  /**
35   * find a type
36   */
37  public class AuditTypeFinder {
38    /** 
39     * every 10 minutes, get new elements
40     */
41    private static GrouperCache<MultiKey, AuditType> types = null;
42  
43    /** 
44     * sister cache to types cache
45     */
46    private static Map<String, AuditType> typesById = null;
47  
48    /**
49     * clear this out, so it will begin again
50     */
51    public static void clearCache() {
52      types = null;
53      typesById = null;
54      updatedBuiltinTypes = false;
55      AuditTypeBuiltin.internal_clearCache();
56    }
57    
58    /** 
59     * Find an {@link AuditType}.
60     * <p/>
61     * @param   auditCategory  Find {@link AuditType} with this name.
62     * @param   auditAction  Find {@link AuditType} with this name.
63     * @param exceptionIfNotFound 
64     * @return  {@link GroupType}
65     */
66    public static AuditType find(String auditCategory, String auditAction, boolean exceptionIfNotFound) {
67      
68      MultiKey multiKey = new MultiKey(auditCategory, auditAction);
69      
70      // First check to see if type is cached.
71      if (types != null && types.containsKey(multiKey)) {
72        return types.get(multiKey);
73      }
74      // If not, refresh known types as it may be new and try again. 
75      internal_updateKnownTypes();
76      if (types.containsKey(multiKey)) {
77        return types.get(multiKey);
78      }
79      if (exceptionIfNotFound) {
80        String msg = "Invalid audit type: category: " + auditCategory + ", action: " + auditAction;
81        throw new RuntimeException(msg);
82      }
83      return null;
84    }
85  
86    /** 
87     * Find an {@link AuditType}.
88     * <p/>
89     * @param   auditCategory  Find {@link AuditType} with this name.
90     * @return  {@link GroupType}
91     */
92    public static Set<AuditType> findByCategory(String auditCategory) {
93      
94      return GrouperDAOFactory.getFactory().getAuditType().findByCategory(auditCategory);
95    }
96  
97    /** 
98     * Find an {@link AuditType}.
99     * <p/>
100    * @param   auditTypeId  Find {@link AuditType} with this id.
101    * @param exceptionIfNotFound 
102    * @return  {@link GroupType}
103    */
104   public static AuditType find(String auditTypeId, boolean exceptionIfNotFound) {
105     
106     // First check to see if type is cached.
107     if (typesById != null && typesById.containsKey(auditTypeId)) {
108       return typesById.get(auditTypeId);
109     }
110     // If not, refresh known types as it may be new and try again. 
111     internal_updateKnownTypes();
112     if (typesById.containsKey(auditTypeId)) {
113       return typesById.get(auditTypeId);
114     }
115     if (exceptionIfNotFound) {
116       String msg = "Invalid audit type id: " + auditTypeId;
117       throw new RuntimeException(msg);
118     }
119     return null;
120   }
121 
122   /**
123    * update the internal cache
124    */
125   public synchronized static void internal_updateKnownTypes() {
126     Set<AuditType> auditTypes = GrouperDAOFactory.getFactory().getAuditType().findAll();
127     GrouperCache<MultiKey, AuditType> newTypes = new GrouperCache<MultiKey, AuditType>(
128         AuditTypeFinder.class.getName() + ".typeCache", 10000, false, 60*10, 60*10, false);
129     
130     Map<String, AuditType> newTypesById = new HashMap<String, AuditType>();
131     
132     for (AuditType auditType : GrouperUtil.nonNull(auditTypes)) {
133       newTypes.put(new MultiKey(auditType.getAuditCategory(), auditType.getActionName()), auditType);
134       newTypesById.put(auditType.getId(), auditType);
135     }
136     
137     //add builtins if necessary
138     internal_updateBuiltinTypesOnce(newTypes, newTypesById);
139     
140     types = newTypes;
141     typesById = newTypesById;
142   }
143   
144   /**
145    * keep track if updated
146    */
147   private static boolean updatedBuiltinTypes = false;
148   
149   /**
150    * update builtin types once
151    * @param newTypes
152    * @param newTypesById 
153    */
154   private static void internal_updateBuiltinTypesOnce(GrouperCache<MultiKey, AuditType> newTypes,
155       Map<String, AuditType> newTypesById) {
156     if (updatedBuiltinTypes && newTypes.getCache().getSize() != 0) {
157       return;
158     }
159     
160     for (AuditTypeBuiltin auditTypeBuiltin : AuditTypeBuiltin.values()) {
161       internal_findOrReplaceAuditType(newTypes, newTypesById, auditTypeBuiltin.internal_auditTypeDefault());
162     }
163   }
164   
165   /**
166    * 
167    * @param newTypes
168    * @param newTypesById 
169    * @param auditType
170    */
171   private static void internal_findOrReplaceAuditType(GrouperCache<MultiKey, AuditType> newTypes, 
172       Map<String, AuditType> newTypesById, AuditType auditType) {
173     MultiKey auditKey = new MultiKey(auditType.getAuditCategory(), auditType.getActionName());
174 
175     //if new
176     if (!newTypes.containsKey(auditKey)) {
177       GrouperDAOFactory.getFactory().getAuditType().saveOrUpdate(auditType);
178       newTypes.put(auditKey, auditType);
179       newTypesById.put(auditType.getId(), auditType);
180     } else {
181 
182       AuditType existingType = newTypes.get(auditKey);
183       if (!existingType.equalsDeep(auditType)) {
184 
185         //if existing and different then copy the new object fields into the existing, and store
186         existingType.copyArgFieldIntoThis(auditType);
187         GrouperDAOFactory.getFactory().getAuditType().saveOrUpdate(existingType);
188       }
189     }
190     
191   }
192   
193   
194 }