1 /**************************************************************
2  *
3  * Licensed to the Apache Software Foundation (ASF) under one
4  * or more contributor license agreements.  See the NOTICE file
5  * distributed with this work for additional information
6  * regarding copyright ownership.  The ASF licenses this file
7  * to you under the Apache License, Version 2.0 (the
8  * "License"); you may not use this file except in compliance
9  * with the License.  You may obtain a copy of the License at
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing,
14  * software distributed under the License is distributed on an
15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16  * KIND, either express or implied.  See the License for the
17  * specific language governing permissions and limitations
18  * under the License.
19  *
20  *************************************************************/
21 
22 
23 package com.sun.star.wizards.ui.event;
24 
25 import java.lang.reflect.Field;
26 import com.sun.star.wizards.common.PropertyNames;
27 import com.sun.star.uno.Any;
28 
29 /**
30  * This class is a factory for Value objects for different types of
31  * memebers.
32  * Other than some Value implementations classes this class contains static
33  * type conversion methods and factory methods.
34  *
35  * @see com.sun.star.wizards.ui.event.DataAware.Value
36  */
37 public class DataAwareFields
38 {
39 
40     private static final String TRUE = "true";
41     private static final String FALSE = "false";
42 
43     /**
44      * returns a Value Object which sets and gets values
45      * and converting them to other types, according to the "value" argument.
46      *
47      * @param owner
48      * @param fieldname
49      * @param value
50      * @return
51      * @throws NoSuchFieldException
52      */
getFieldValueFor(Object owner, String fieldname, Object value)53     public static DataAware.Value getFieldValueFor(Object owner, String fieldname, Object value)
54     {
55         try
56         {
57             Field f = owner.getClass().getField(fieldname);
58 
59             Class c = f.getType();
60             Class c2 = value.getClass();
61             if (c.equals(Boolean.TYPE))
62             {
63                 return new BooleanFieldValue(f, c2);
64             }
65             else if (c.equals(Integer.TYPE))
66             {
67                 return new IntFieldValue(f, c2);
68             }
69             else if (c.equals(Double.TYPE))
70             {
71                 return new DoubleFieldValue(f, c2);
72             }
73             else if (c.equals(String.class) && c2.equals(Integer.class))
74             {
75                 return new ConvertedStringValue(f, c2);
76             }
77             else
78             {
79                 return new SimpleFieldValue(f);
80             }
81         }
82         catch (NoSuchFieldException ex)
83         {
84             ex.printStackTrace();
85             return null;
86         }
87     }
88 
89     /**
90      * an abstract implementation of DataAware.Value to access
91      * object memebers (fields) usign reflection.
92      */
93     private static abstract class FieldValue implements DataAware.Value
94     {
95 
96         Field field;
97 
FieldValue(Field field_)98         public FieldValue(Field field_)
99         {
100             field = field_;
101         }
102 
isAssignable(Class type)103         public boolean isAssignable(Class type)
104         {
105             return field.getDeclaringClass().isAssignableFrom(type);
106         }
107     }
108 
109     private static class BooleanFieldValue extends FieldValue
110     {
111 
112         private Class convertTo;
113 
BooleanFieldValue(Field f, Class convertTo_)114         public BooleanFieldValue(Field f, Class convertTo_)
115         {
116             super(f);
117             convertTo = convertTo_;
118         }
119 
120         /* (non-Javadoc)
121          * @see com.sun.star.wizards.ui.event.DataAware.Value#get(java.lang.Object)
122          */
get(Object target)123         public Object get(Object target)
124         {
125             try
126             {
127                 boolean b = field.getBoolean(target);
128                 if (convertTo.equals(Boolean.class))
129                 {
130                     return b ? Boolean.TRUE : Boolean.FALSE;
131                 }
132                 else if (Number.class.isAssignableFrom(convertTo))
133                 {
134                     return toNumber(b ? 1 : 0, convertTo);
135                 }
136                 else if (convertTo.equals(String.class))
137                 {
138                     return String.valueOf(b);
139                 }
140                 else if (convertTo.isArray())
141                 {
142                     return toShortArray(toInt(b));
143                 }
144                 else
145                 {
146                     throw new IllegalArgumentException("Cannot convert boolean value to given type (" + convertTo.getName() + ").");
147                 }
148             }
149             catch (IllegalAccessException ex)
150             {
151                 ex.printStackTrace();
152                 return null;
153             }
154         }
155 
set(Object value, Object target)156         public void set(Object value, Object target)
157         {
158             try
159             {
160                 field.setBoolean(target, toBoolean(value));
161             }
162             catch (IllegalAccessException ex)
163             {
164                 ex.printStackTrace();
165             }
166         }
167     }
168 
169     private static class IntFieldValue extends FieldValue
170     {
171 
172         private Class convertTo;
173 
IntFieldValue(Field f, Class convertTo_)174         public IntFieldValue(Field f, Class convertTo_)
175         {
176             super(f);
177             convertTo = convertTo_;
178         }
179 
180         /* (non-Javadoc)
181          * @see com.sun.star.wizards.ui.event.DataAware.Value#get(java.lang.Object)
182          */
get(Object target)183         public Object get(Object target)
184         {
185             try
186             {
187                 int i = field.getInt(target);
188                 if (convertTo.equals(Boolean.class))
189                 {
190                     return i != 0 ? Boolean.TRUE : Boolean.FALSE;
191                 }
192                 else if (Number.class.isAssignableFrom(convertTo))
193                 {
194                     return toNumber(i, convertTo);
195                 }
196                 else if (convertTo.equals(String.class))
197                 {
198                     return String.valueOf(i);
199                 }
200                 else if (convertTo.isArray())
201                 {
202                     return toShortArray(i);
203                 }
204                 else
205                 {
206                     throw new IllegalArgumentException("Cannot convert int value to given type (" + convertTo.getName() + ").");
207                 }
208             }
209             catch (IllegalAccessException ex)
210             {
211                 ex.printStackTrace();
212                 return null;
213             }
214         }
215 
set(Object value, Object target)216         public void set(Object value, Object target)
217         {
218             try
219             {
220                 field.setInt(target, (int) toDouble(value));
221             }
222             catch (IllegalAccessException ex)
223             {
224                 ex.printStackTrace();
225             }
226         }
227     }
228 
229     private static class DoubleFieldValue extends FieldValue
230     {
231 
232         private Class convertTo;
233 
DoubleFieldValue(Field f, Class convertTo_)234         public DoubleFieldValue(Field f, Class convertTo_)
235         {
236             super(f);
237             convertTo = convertTo_;
238         }
239 
240         /* (non-Javadoc)
241          * @see com.sun.star.wizards.ui.event.DataAware.Value#get(java.lang.Object)
242          */
get(Object target)243         public Object get(Object target)
244         {
245             try
246             {
247                 double d = field.getDouble(target);
248                 if (convertTo.equals(Boolean.class))
249                 {
250                     return d != 0 ? Boolean.TRUE : Boolean.FALSE;
251                 }
252                 else if (Number.class.isAssignableFrom(convertTo))
253                 {
254                     return toNumber(d, convertTo);
255                 }
256                 else if (convertTo.equals(String.class))
257                 {
258                     return String.valueOf(d);
259                 }
260                 else if (convertTo.isArray())
261                 {
262                     return toShortArray(d);
263                 }
264                 else
265                 {
266                     throw new IllegalArgumentException("Cannot convert int value to given type (" + convertTo.getName() + ").");
267                 }
268             }
269             catch (IllegalAccessException ex)
270             {
271                 ex.printStackTrace();
272                 return null;
273             }
274         }
275 
set(Object value, Object target)276         public void set(Object value, Object target)
277         {
278             try
279             {
280                 field.setDouble(target, toDouble(value));
281             }
282             catch (IllegalAccessException ex)
283             {
284                 ex.printStackTrace();
285             }
286         }
287     }
288 
289     private static class ConvertedStringValue extends FieldValue
290     {
291 
292         private Class convertTo;
293 
ConvertedStringValue(Field f, Class convertTo_)294         public ConvertedStringValue(Field f, Class convertTo_)
295         {
296             super(f);
297             convertTo = convertTo_;
298         }
299 
300         /* (non-Javadoc)
301          * @see com.sun.star.wizards.ui.event.DataAware.Value#get(java.lang.Object)
302          */
get(Object target)303         public Object get(Object target)
304         {
305             try
306             {
307                 String s = (String) field.get(target);
308 
309                 if (convertTo.equals(Boolean.class))
310                 {
311                     return (s != null && !s.equals(PropertyNames.EMPTY_STRING) && s.equals("true")) ? Boolean.TRUE : Boolean.FALSE;
312                 }
313                 else if (convertTo.equals(Integer.class))
314                 {
315                     if (s == null || s.equals(PropertyNames.EMPTY_STRING))
316                     {
317                         return Any.VOID;
318                     }
319                     else
320                     {
321                         return new Integer(s);
322                     }
323                 }
324                 else if (convertTo.equals(Double.class))
325                 {
326                     if (s == null || s.equals(PropertyNames.EMPTY_STRING))
327                     {
328                         return Any.VOID;
329                     }
330                     else
331                     {
332                         return new Double(s);
333                     }
334                 }
335                 else
336                 {
337                     throw new IllegalArgumentException("Cannot convert int value to given type (" + convertTo.getName() + ").");
338                 }
339             }
340             catch (IllegalAccessException ex)
341             {
342                 ex.printStackTrace();
343                 return null;
344             }
345         }
346 
set(Object value, Object target)347         public void set(Object value, Object target)
348         {
349             try
350             {
351                 field.set(target, value == null || (value.equals(Any.VOID)) ? PropertyNames.EMPTY_STRING : value.toString());
352             }
353             catch (IllegalAccessException ex)
354             {
355                 ex.printStackTrace();
356             }
357         }
358     }
359 
360     private static class SimpleFieldValue extends FieldValue
361     {
362 
SimpleFieldValue(Field f)363         public SimpleFieldValue(Field f)
364         {
365             super(f);
366         }
367         /* (non-Javadoc)
368          * @see com.sun.star.wizards.ui.event.DataAware.Value#get(java.lang.Object)
369          */
370 
get(Object target)371         public Object get(Object target)
372         {
373             try
374             {
375                 if (target == null)
376                 {
377                     if (field.getType().equals(String.class))
378                     {
379                         return PropertyNames.EMPTY_STRING;
380                     }
381                     if (field.getType().equals(Short.class))
382                     {
383                         return new Short((short) 0);
384                     }
385                     if (field.getType().equals(Integer.class))
386                     {
387                         return 0;
388                     }
389                     if (field.getType().equals(short[].class))
390                     {
391                         return new short[0];
392                     }
393                     else
394                     {
395                         return null;
396                     }
397                 }
398                 else
399                 {
400                     return field.get(target);
401                 }
402             }
403             catch (IllegalAccessException ex)
404             {
405                 ex.printStackTrace();
406                 return null;
407             }
408         }
409 
set(Object value, Object target)410         public void set(Object value, Object target)
411         {
412             try
413             {
414                 field.set(target, value);
415             }
416             catch (IllegalAccessException ex)
417             {
418                 ex.printStackTrace();
419             }
420         }
421     }
422 
toDouble(Object value)423     private static double toDouble(Object value)
424     {
425         if (value instanceof Boolean)
426         {
427             return ((Boolean) value).booleanValue() ? 1 : 0;
428         }
429         else if (value instanceof Number)
430         {
431             return ((Number) value).doubleValue();
432         }
433         else if (value instanceof String)
434         {
435             return Double.valueOf((String) value).doubleValue();
436         }
437         else if (value instanceof short[])
438         {
439             return ((short[]) value).length == 0 ? 0 : ((short[]) value)[0];
440         }
441         else
442         {
443             throw new IllegalArgumentException("Can't convert value to double." + value.getClass().getName());
444         }
445     }
446 
toBoolean(Object value)447     private static boolean toBoolean(Object value)
448     {
449         if (value instanceof Boolean)
450         {
451             return ((Boolean) value).booleanValue();
452         }
453         else if (value instanceof Number)
454         {
455             return ((Number) value).intValue() != 0;
456         }
457         else if (value instanceof String)
458         {
459             return value.equals(TRUE);
460         }
461         else if (value instanceof short[])
462         {
463             return ((short[]) value).length != 0 && ((short[]) value)[0] != 0;
464         }
465         else
466         {
467             throw new IllegalArgumentException("Can't convert value to boolean." + value.getClass().getName());
468         }
469     }
470 
toInt(boolean b)471     private static int toInt(boolean b)
472     {
473         return b ? 1 : 0;
474     }
475 
toShortArray(double i)476     private static short[] toShortArray(double i)
477     {
478         return new short[]
479                 {
480                     (short) i
481                 };
482     }
483 
toNumber(double i, Class c)484     private static Number toNumber(double i, Class c)
485     {
486         if (c.equals(Integer.class))
487         {
488             return new Integer((int) i);
489         }
490         else if (c.equals(Short.class))
491         {
492             return new Short((short) i);
493         }
494         else if (c.equals(Double.class))
495         {
496             return new Double(i);
497         }
498         else
499         {
500             throw new IllegalArgumentException("Cannot convert to the given Number type.");
501         }
502     }
503 }
504