1   /*
2    * Copyright 2003 - 2013 The eFaps Team
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   * Revision:        $Rev$
17   * Last Changed:    $Date$
18   * Last Changed By: $Author$
19   */
20  
21  package org.efaps.admin.ui.field;
22  
23  import java.util.List;
24  
25  import org.efaps.admin.access.AccessType;
26  import org.efaps.admin.access.AccessTypeEnums;
27  import org.efaps.admin.datamodel.Classification;
28  import org.efaps.admin.event.EventDefinition;
29  import org.efaps.admin.event.EventType;
30  import org.efaps.admin.event.Parameter;
31  import org.efaps.admin.event.Parameter.ParameterValues;
32  import org.efaps.admin.event.Return;
33  import org.efaps.admin.event.Return.ReturnValues;
34  import org.efaps.admin.ui.AbstractCommand;
35  import org.efaps.db.Context;
36  import org.efaps.db.Instance;
37  import org.efaps.jaas.AppAccessHandler;
38  import org.efaps.util.EFapsException;
39  
40  /**
41   * TODO comment!
42   *
43   * @author The eFaps Team
44   * @version $Id: FieldClassification.java 9468 2013-05-19 02:21:22Z
45   *          jan@moxter.net $
46   */
47  public class FieldClassification
48      extends Field
49  {
50  
51      /**
52       * Needed for serialization.
53       */
54      private static final long serialVersionUID = 1L;
55  
56      /**
57       * This is the constructor of the field class.
58       *
59       * @param _id id of the field instance
60       * @param _uuid UUID of the field instance
61       * @param _name name of the field instance
62       */
63      public FieldClassification(final long _id,
64                                 final String _uuid,
65                                 final String _name)
66      {
67          super(_id, _uuid, _name);
68      }
69  
70      /**
71       * {@inheritDoc}
72       */
73      @Override
74      public boolean hasAccess(final TargetMode _targetMode,
75                               final Instance _instance,
76                               final AbstractCommand _callCmd,
77                               final Instance _callInstance)
78          throws EFapsException
79      {
80          boolean ret = false;
81          final String[] names = getClassificationName().split(";");
82          for (final String className : names) {
83              if (Classification.get(className) != null && Classification.get(className)
84                                              .isAssigendTo(Context.getThreadContext().getCompany())
85                              && !AppAccessHandler.excludeMode()) {
86                  final Classification clazz = Classification.get(className);
87                  // check if any of the type ahs access
88                  ret = checkAccessOnChild(clazz, _instance, _targetMode == TargetMode.CREATE
89                                  || _targetMode == TargetMode.EDIT ? AccessTypeEnums.CREATE.getAccessType()
90                                  : AccessTypeEnums.SHOW.getAccessType());
91                  if (ret) {
92                      break;
93                  }
94              }
95          }
96          if ((ret || AppAccessHandler.excludeMode()) && super.hasEvents(EventType.UI_ACCESSCHECK)) {
97              ret = false;
98              final List<EventDefinition> events = super.getEvents(EventType.UI_ACCESSCHECK);
99  
100             final Parameter parameter = new Parameter();
101             parameter.put(ParameterValues.UIOBJECT, this);
102             parameter.put(ParameterValues.ACCESSMODE, _targetMode);
103             parameter.put(ParameterValues.INSTANCE, _instance);
104             parameter.put(ParameterValues.CALL_CMD, _callCmd);
105             parameter.put(ParameterValues.CALL_INSTANCE, _callInstance);
106             for (final EventDefinition event : events) {
107                 final Return retIn = event.execute(parameter);
108                 ret = retIn.get(ReturnValues.TRUE) != null;
109             }
110         }
111         return ret;
112     }
113 
114     /**
115      * @param _parent parent to iterate down
116      * @param _instance instance to check
117      * @param _accessType   accesstype
118      * @return true of access is granted
119      * @throws EFapsException on error
120      */
121     private boolean checkAccessOnChild(final Classification _parent,
122                                        final Instance _instance,
123                                        final AccessType _accessType)
124         throws EFapsException
125     {
126         boolean ret = false;
127         if (!_parent.isAbstract()) {
128             ret = _parent.hasAccess(getInstance4Classification(_instance, _parent), _accessType);
129         }
130         if (!ret) {
131             for (final Classification childClass : _parent.getChildClassifications()) {
132                 ret = childClass.hasAccess(getInstance4Classification(_instance, childClass), _accessType);
133                 if (ret) {
134                     break;
135                 }
136             }
137         }
138         return ret;
139     }
140 
141     /**
142      * @param _instance Instance of the classifcation
143      * @param _clazz    classification to be searched
144      * @return Instance of the classification
145      */
146     private Instance getInstance4Classification(final Instance _instance,
147                                                 final Classification _clazz)
148     {
149         Instance inst = _instance;
150         if (!(_instance.getType() instanceof Classification)) {
151             inst = Instance.get(_clazz, 0);
152         }
153         return inst;
154     }
155 }