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.containerdefinition;
17  
18  import static fulmine.util.Utils.CLOSE_SQUARE;
19  import static fulmine.util.Utils.COMMA_SPACE;
20  import fulmine.IType;
21  import fulmine.Type;
22  import fulmine.context.IPermissionProfile;
23  import fulmine.model.field.AbstractField;
24  import fulmine.model.field.BooleanField;
25  import fulmine.model.field.DoubleField;
26  import fulmine.model.field.FloatField;
27  import fulmine.model.field.IField;
28  import fulmine.model.field.IntegerField;
29  import fulmine.model.field.LongField;
30  import fulmine.model.field.StringField;
31  import fulmine.protocol.specification.ByteReader;
32  import fulmine.protocol.specification.FieldWriter;
33  import fulmine.protocol.wire.IWireIdentity;
34  import fulmine.protocol.wire.operation.IOperationScope;
35  import fulmine.util.log.AsyncLog;
36  import fulmine.util.reference.is;
37  
38  /**
39   * A field that holds the description of the structure of a single
40   * {@link IField} in a container. The description contains the identity, IWF
41   * wire code, data type, application code and permission code of the target
42   * field. The identity of this field is the identity of the field it describes.
43   * <p>
44   * The descriptor writes the field attributes as follows:
45   * 
46   * <pre>
47   * -------------------------------------------------------------------------------------------------------------------------
48   * |   8th byte   |   7th byte   |   6th byte   |   5th byte   |   4th byte   |   3rd byte   |   2nd byte   |   1st byte   |
49   * -------------------------------------------------------------------------------------------------------------------------
50   * |                         wire code                         |         permission          |     type     | application  |
51   * -------------------------------------------------------------------------------------------------------------------------
52   * </pre>
53   * 
54   * @author Ramon Servadei
55   */
56  public final class DescriptorField extends AbstractField
57  {
58      private final static AsyncLog LOG = new AsyncLog(DescriptorField.class);
59  
60      @Override
61      protected AsyncLog getLog()
62      {
63          return LOG;
64      }
65  
66      /** The wire code for the field */
67      private int wireCode;
68  
69      /**
70       * The data type of the field.
71       * 
72       * @see Type Type for the possible values
73       */
74      private byte dataType;
75  
76      /**
77       * Standard constructor
78       * 
79       * @param identity
80       *            the identity of this field AND the identity of the field this
81       *            describes
82       */
83      public DescriptorField(String identity)
84      {
85          super(identity, Type.DESCRIPTOR_FIELD,
86              IPermissionProfile.DEFAULT_APPLICATION,
87              IPermissionProfile.DEFAULT_PERMISSION);
88      }
89  
90      public IField createField()
91      {
92          final IType type = Type.get(getDataType());
93          if (type.equals(Type.BOOLEAN_FIELD))
94          {
95              return new BooleanField(getFieldIdentity(), getApplication(),
96                  getPermission());
97          }
98          if (type.equals(Type.INTEGER_FIELD))
99          {
100             return new IntegerField(getFieldIdentity(), getApplication(),
101                 getPermission());
102         }
103         if (type.equals(Type.LONG_FIELD))
104         {
105             return new LongField(getFieldIdentity(), getApplication(),
106                 getPermission());
107         }
108         if (type.equals(Type.FLOAT_FIELD))
109         {
110             return new FloatField(getFieldIdentity(), getApplication(),
111                 getPermission());
112         }
113         if (type.equals(Type.DOUBLE_FIELD))
114         {
115             return new DoubleField(getFieldIdentity(), getApplication(),
116                 getPermission());
117         }
118         if (type.equals(Type.STRING_FIELD))
119         {
120             return new StringField(getFieldIdentity(), getApplication(),
121                 getPermission());
122         }
123         throw new IllegalArgumentException("Unhandled field type: " + type);
124     }
125 
126     public void setWireCode(int wireCode)
127     {
128         this.wireCode = wireCode;
129     }
130 
131     public void setDataType(byte type)
132     {
133         this.dataType = type;
134     }
135 
136     String getFieldIdentity()
137     {
138         return getIdentity();
139     }
140 
141     public int getWireCode()
142     {
143         return this.wireCode;
144     }
145 
146     public byte getDataType()
147     {
148         return this.dataType;
149     }
150 
151     @Override
152     protected boolean doReadState(IOperationScope scope, byte[] buffer,
153         int start, int numberOfBytes) throws Exception
154     {
155         long state = ByteReader.readLong(buffer, start, numberOfBytes);
156         setWireCode((int) (state >> 32));
157         setPermission((short) ((state >> 16) & 0xFFFF));
158         setDataType((byte) ((state >> 8) & 0xFF));
159         setApplication((byte) (state & 0xFF));
160         return true;
161     }
162 
163     @Override
164     protected boolean doWriteState(IOperationScope scope, IWireIdentity wireId,
165         byte[][] headerBuffer, int[] headerBufferPosition, byte[][] dataBuffer,
166         int[] dataBufferPosition, boolean completeState) throws Exception
167     {
168         long state = (long) getWireCode() << 32;
169         state |= (getPermission() << 16) & 0x00000000FFFF0000L;
170         state |= (getDataType() << 8) & 0xFF00;
171         state |= (getApplication() & 0xFF);
172         FieldWriter.writeLongField(wireId, state, headerBuffer,
173             headerBufferPosition, dataBuffer, dataBufferPosition);
174         return true;
175     }
176 
177     public String getValueAsString()
178     {
179         return toString();
180     }
181 
182     public Object getValue()
183     {
184         return getValueAsString();
185     }
186 
187     @Override
188     public String toString()
189     {
190         return "[DescriptorField " + getIdentity() + COMMA_SPACE
191             + Type.get(getDataType()) + COMMA_SPACE + getWireCode()
192             + COMMA_SPACE + getApplication() + COMMA_SPACE + getPermission()
193             + CLOSE_SQUARE;
194     }
195 
196     @Override
197     public int hashCode()
198     {
199         final int prime = 31;
200         int result = super.hashCode();
201         result = prime * result + getWireCode();
202         result = prime * result + getDataType();
203         return result;
204     }
205 
206     @Override
207     public boolean equals(Object obj)
208     {
209         if (is.same(this, obj))
210         {
211             return true;
212         }
213         if (is.differentClass(this, obj))
214         {
215             return false;
216         }
217         if (super.equals(obj))
218         {
219             final DescriptorField other = (DescriptorField) obj;
220             return is.eq(getDataType(), other.getDataType())
221                 && is.eq(getWireCode(), other.getWireCode());
222         }
223         return false;
224     }
225 }