View Javadoc

1   /*
2      Copyright 2007 Ramon Servadei
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  package fulmine.model.field;
17  
18  import static fulmine.util.Utils.COLON;
19  import static fulmine.util.Utils.COMMA_SPACE;
20  import static fulmine.util.Utils.string;
21  import fulmine.Domain;
22  import fulmine.IType;
23  import fulmine.event.EventProcessor;
24  import fulmine.event.IEvent;
25  import fulmine.model.component.AbstractComponent;
26  import fulmine.model.container.IContainer;
27  import fulmine.util.reference.is;
28  
29  /**
30   * The base-class for all {@link IField} implementations. All implementations
31   * will include a setter and getter for the field's value. A field is added as a
32   * member of an {@link IContainer}.
33   * <p>
34   * If a field is set with a different value, the field will raise an event with
35   * its container. If the field is set with the same value, no event is raised.
36   * <p>
37   * Field implementations are not guaranteed to be thread-safe.
38   * 
39   * @author Ramon Servadei
40   */
41  public abstract class AbstractField extends AbstractComponent implements IField
42  {
43      /** The container this field is held in */
44      private IContainer container;
45  
46      /** The application that created the field */
47      private byte application;
48  
49      /** The permission assigned for the field by the application */
50      private short permission;
51  
52      /**
53       * Standard constructor.
54       * 
55       * @param identity
56       *            the identity of the field
57       * @param type
58       *            the type of the field
59       * @param application
60       *            the application that created the field
61       * @param permission
62       *            the permission assigned for the field by the application
63       */
64      public AbstractField(String identity, IType type, byte application,
65          short permission)
66      {
67          super(identity, type, Domain.FRAMEWORK);
68          this.application = application;
69          this.permission = permission;
70      }
71  
72      public final IContainer getContainer()
73      {
74          return this.container;
75      }
76  
77      public byte getApplication()
78      {
79          return this.application;
80      }
81  
82      public short getPermission()
83      {
84          return this.permission;
85      }
86  
87      public final void addedToContainer(IContainer container)
88      {
89          setContainer(container);
90      }
91  
92      public final void removedFromContainer(IContainer container)
93      {
94          if (getContainer() != null && getContainer().equals(container))
95          {
96              setContainer(null);
97          }
98      }
99  
100     @Override
101     protected void doComponentDestroy()
102     {
103         super.doComponentDestroy();
104         setContainer(null);
105     }
106 
107     /**
108      * Notify the container with an event
109      * 
110      * @param event
111      *            the event to notify the container with
112      */
113     protected final void notifyEvent(IEvent event)
114     {
115         checkClone();
116         /*
117          * Get the thread-bound {@link IEventFrameExecution} from the {@link
118          * EventProcessor} currently executing and store it. This becomes known
119          * as the 'driving' frame as it drives the change in this field.
120          */
121         setDrivingFrame(EventProcessor.getCurrentFrame());
122         if (getContainer() != null)
123         {
124             getContainer().addEvent(event);
125         }
126     }
127 
128     public final void setContainer(IContainer container)
129     {
130         this.container = container;
131     }
132 
133     public void setApplication(byte application)
134     {
135         this.application = application;
136     }
137 
138     public void setPermission(short permission)
139     {
140         this.permission = permission;
141     }
142 
143     @Override
144     public String toIdentityString()
145     {
146         return getFormattedString(string(this,
147             getIdentityStringWithPermission().toString()));
148     }
149 
150     @Override
151     public String toString()
152     {
153         return getFormattedString(string(this,
154             getIdentityStringWithPermission().append(COMMA_SPACE).append(
155                 "value=").append(getValueAsString()).toString()));
156     }
157 
158     @Override
159     public String toDetailedString()
160     {
161         return toString();
162     }
163 
164     @Override
165     public int hashCode()
166     {
167         final int prime = 31;
168         int result = super.hashCode();
169         result = prime * result + getPermission();
170         result = prime * result + getApplication();
171         return result;
172     }
173 
174     @Override
175     public boolean equals(Object obj)
176     {
177         if (is.same(this, obj))
178         {
179             return true;
180         }
181         if (is.differentClass(this, obj))
182         {
183             return false;
184         }
185         if (super.equals(obj))
186         {
187             final AbstractField other = (AbstractField) obj;
188             return is.eq(getPermission(), other.getPermission())
189                 && is.eq(getApplication(), other.getApplication());
190         }
191         return false;
192     }
193 
194     /**
195      * Get a formatted string containing the container's identity (if the field
196      * is attached to a container) and the field string value
197      * 
198      * @param fieldStringValue
199      *            the string value for the field
200      * @return a formatted string with the container and string value
201      */
202     private String getFormattedString(final String fieldStringValue)
203     {
204         return getContainer() == null ? fieldStringValue
205             : getContainer().toIdentityString() + COLON + COLON
206                 + fieldStringValue;
207     }
208 
209     private StringBuilder getIdentityStringWithPermission()
210     {
211         return getIdentityString().append(COMMA_SPACE).append("application=").append(
212             getApplication()).append(COMMA_SPACE).append("permission=").append(
213             getPermission());
214     }
215 
216     public boolean setValueFromString(String value)
217     {
218         throw new UnsupportedOperationException();
219     }
220 }