View Javadoc

1   package com.sourceforge.jpatterns.patterns;
2   
3   import com.sourceforge.jpatterns.core.configuration.exceptions.JPConfigException;
4   import com.sourceforge.jpatterns.core.configuration.model.JPatternsConfigsBean;
5   import com.sourceforge.jpatterns.patterns.factory.JPFactoryImpl;
6   import com.sourceforge.jpatterns.schema.CastorNameScopePriorityType;
7   import com.sourceforge.jpatterns.schema.CastorSectionType;
8   import com.sourceforge.jpatterns.schema.Item;
9   import com.zmicer.utils.InputArgumentUtils;
10  import com.zmicer.utils.LoggingUtils;
11  import com.zmicer.utils.ObjectStateUtils;
12  import com.zmicer.utils.ReflexionUtils;
13  import org.apache.commons.lang.StringUtils;
14  import org.apache.log4j.Logger;
15  
16  /**
17   * The abstratc class to implement the IJPattern - provides base facilities for all the IJPattern implementations.
18   *
19   * todo [zmicer]: tests redesign - move from JPFactoryImpl to this class test
20   *
21   * $Author::                    $<br/>
22   * $Rev::                       $<br/>
23   * $Date::                      $<br/>
24   */
25  public abstract class PatternBase implements IJPattern
26  {
27      /**
28       * Logger instance.
29       */
30      final public static Logger LOG = Logger.getLogger(PatternBase.class);
31  
32      /**
33       * The castor config object used for the storing business info.
34       * <br>
35       * For now we use only the name of the section which is get from this castor object, still it is necessary for us in any case -
36       * potentially we could start use it but not the {@link JPatternsConfigsBean} which is the JPatterns consumer configuration entry point.
37       */
38      protected CastorSectionType m_castorSection = null;
39  
40      /**
41       * The config bean - is a wrapper under the Factory castor config bean. We would use it for all the "get" operations. It is convenient
42       * as allow us access the sections and business items using the path: section name and business item name.
43       */
44      protected JPatternsConfigsBean m_configBean = null;
45  
46      /**
47       * @see com.sourceforge.jpatterns.patterns.IJPattern#checkCastorConfig(com.sourceforge.jpatterns.schema.CastorSectionType)
48       */
49      public abstract boolean checkCastorConfig(CastorSectionType castorSectionType);
50  
51      /**
52       * @see IJPattern#init(com.sourceforge.jpatterns.schema.CastorSectionType,
53          com.sourceforge.jpatterns.core.configuration.model.JPatternsConfigsBean)
54       */
55      public void init(CastorSectionType castorSectionType, JPatternsConfigsBean configBean)
56      {
57          InputArgumentUtils.checkObjects(castorSectionType, configBean);
58          if (!(checkCastorConfig(castorSectionType)))
59          {
60              final String errorMessage = "Error during initializing the pattern - the provided CastorSectionType object is not of " +
61                  "appropriate type. It's scope [" + castorSectionType.getScope() + "], name [" + castorSectionType.getName() + "].";
62              LoggingUtils.error(LOG, JPFactoryImpl.class, errorMessage);
63              throw new JPConfigException(errorMessage);
64          }
65          m_castorSection = castorSectionType;
66          m_configBean = configBean;
67      }
68  
69      /**
70       * @see com.zmicer.utils.model.ICheckable#check()
71       */
72      public boolean check()
73      {
74          return (null != m_castorSection && null != m_configBean &&
75              !StringUtils.isBlank(m_castorSection.getName()) && !StringUtils.isBlank(m_castorSection.getScope()));
76      }
77  
78      /**
79       * Get the actual scope. In the case the provided scope variable is not null - it would be returned, otherwise - the scope of the
80       * provided CastorSectionType.
81       *
82       * @param scope   the scope variable to be checked. Could be null, in this case we would deal with the scope of the section type
83       * @param section the castor section scope of which would be used (in any case this object and its scope can not be null)
84       *
85       * @return the actual scope to be used
86       */
87      protected String getActualScope(final String scope, final CastorSectionType section)
88      {
89          InputArgumentUtils.checkObjects(section, section.getScope());
90          return (StringUtils.isNotBlank(scope)) ? scope : section.getScope();
91      }
92  
93  
94      /**
95       * Retrieve the item object from the castor factory storing in this model factory object using the provided information:
96       * the name of the business item and the scope provided. In the case scope is blank we use the default scope defined at the
97       * castor factory type.
98       * note [zmicer]: the CastorNameScopePriorityType item is got here is validated (it has not blank name). The composition of validation
99       * could be adjusted.
100      *
101      * @param nameStorage the name of the Item to be retrieved. Can not be null (otherwise <code>IllegalArgumentException</code> would
102      *                    appear).
103      * @param scope       the scope we need to use, could be <code>null</code>.
104      *
105      * @return the Item we would use later for the concrete IJPFactory implementation
106      */
107     protected Item retrieveItem(final Object nameStorage, final String scope)
108     {
109         InputArgumentUtils.checkObjects(nameStorage);
110         if (!(nameStorage instanceof String) && !(nameStorage instanceof Class))
111         {
112             logAndThrow("Smth. wrong at the com.sourceforge.jpatterns.patterns.factory.JPFactoryImpl.retrieveItem. Wrong " +
113                 "storage for the name is passed. Check the algorithm");
114         }
115         if (nameStorage instanceof String)
116         {
117             InputArgumentUtils.checkStrings(true, (String) nameStorage);
118         }
119         ObjectStateUtils.strongCheck(this);
120         final String baseName = (nameStorage instanceof String) ? (String) nameStorage : ReflexionUtils.getBaseName((Class) nameStorage);
121         String workingScope = getActualScope(scope, m_castorSection);
122 
123         final CastorNameScopePriorityType castorNameScopePriorityType =
124             m_configBean.getBusinessItem(m_castorSection.getScope(), m_castorSection.getName(), workingScope, baseName);
125         if (!(castorNameScopePriorityType instanceof Item))
126         {
127             throw new JPConfigException("Factory should contains items of Item type inside.");
128         }
129         if (StringUtils.isBlank(castorNameScopePriorityType.getName()))
130         {
131             throw new JPConfigException("Smth. wrong with the configuration as the name of the CastorNameScopePriorityType type is " +
132                 "required.");
133         }
134         return (Item) castorNameScopePriorityType;
135     }
136 
137     /**
138      * Log the message and then throw it.
139      *
140      * todo [zmicer]: possible it would be adjusted as it should throw the exception of the two types - depending on the category
141      *
142      * @param message the not emopty message to be thrown and logged
143      *
144      * @throws JPConfigException always, using message
145      */
146     protected void logAndThrow(final String message) throws JPConfigException
147     {
148         InputArgumentUtils.checkStrings(true, message);
149         LoggingUtils.error(LOG, JPFactoryImpl.class, message);
150         throw new JPConfigException(message);
151     }
152 }