001    /*
002     * Copyright 2004 Chris Nelson
003     *
004     * Licensed under the Apache License, Version 2.0 (the "License");
005     * you may not use this file except in compliance with the License.
006     * You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
007     * Unless required by applicable law or agreed to in writing,
008     * software distributed under the License is distributed on an "AS IS" BASIS,
009     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
010     * See the License for the specific language governing permissions and limitations under the License.
011     */
012    package org.trails.descriptor;
013    
014    import java.lang.reflect.InvocationTargetException;
015    import java.util.ArrayList;
016    import java.util.List;
017    
018    import ognl.Ognl;
019    import ognl.OgnlException;
020    import org.apache.commons.beanutils.BeanUtils;
021    import org.trails.util.Utils;
022    
023    /**
024     * This represents all the Trails metadata for a single class.
025     */
026    public class TrailsClassDescriptor extends TrailsDescriptor implements
027            IClassDescriptor
028    {
029            private List<IPropertyDescriptor> propertyDescriptors = new ArrayList<IPropertyDescriptor>();
030    
031            private List<IMethodDescriptor> methodDescriptors = new ArrayList<IMethodDescriptor>();
032    
033            // private BeanDescriptor beanDescriptor;
034            private boolean child;
035    
036            boolean hasCyclicRelationships;
037    
038            boolean allowRemove = true;
039    
040            boolean allowSave = true;
041    
042            // ///////////////////////////////////////////////////////////////////////////////////////////////////////
043            // Constructors
044            // ///////////////////////////////////////////////////////////////////////////////////////////////////////
045            /**
046             * This is a copy constructor. These need to be clonable for the security
047             * aspect to be able to copy them, so if new properties are added they
048             * should be added here too.
049             */
050            public TrailsClassDescriptor(IClassDescriptor descriptor)
051            {
052                    super(descriptor);
053                    copyPropertyDescriptorsFrom(descriptor);
054                    copyMethodDescriptorsFrom(descriptor);
055            }
056    
057            public TrailsClassDescriptor(Class type)
058            {
059                    super(type);
060            }
061    
062            public TrailsClassDescriptor(Class type, String displayName)
063            {
064                    super(type);
065                    this.setDisplayName(displayName);
066            }
067    
068            /**
069             * @param dto
070             */
071            public TrailsClassDescriptor(TrailsClassDescriptor dto)
072            {
073                    super(dto);
074    
075                    try
076                    {
077                            BeanUtils.copyProperties(this, dto);
078                    } catch (IllegalAccessException e)
079                    {
080                            LOG.error(e.getMessage());
081                            e.printStackTrace();
082                    } catch (InvocationTargetException e)
083                    {
084                            LOG.error(e.getMessage());
085                            e.printStackTrace();
086                    } catch (Exception e)
087                    {
088                            LOG.error(e.toString());
089                            e.printStackTrace();
090                    }
091            }
092    
093            // ///////////////////////////////////////////////////////////////////////////////////////////////////////
094            // Methods
095            // ///////////////////////////////////////////////////////////////////////////////////////////////////////
096            private void copyMethodDescriptorsFrom(IClassDescriptor descriptor)
097            {
098                    for (IMethodDescriptor methodDescriptor : descriptor
099                            .getMethodDescriptors())
100                    {
101                            getMethodDescriptors().add(
102                                    IMethodDescriptor.class.cast(methodDescriptor.clone()));
103                    }
104            }
105    
106            protected void copyPropertyDescriptorsFrom(IClassDescriptor descriptor)
107            {
108                    for (IPropertyDescriptor iPropertyDescriptor : descriptor
109                            .getPropertyDescriptors())
110                    {
111                            getPropertyDescriptors()
112                                    .add(
113                                            IPropertyDescriptor.class.cast(iPropertyDescriptor
114                                                    .clone()));
115                    }
116            }
117    
118            /**
119             * @param ognl
120             * @return
121             */
122            private IPropertyDescriptor findDescriptor(String ognl)
123            {
124                    try
125                    {
126                            return (IPropertyDescriptor) Ognl.getValue(ognl, this);
127                    } catch (OgnlException oe)
128                    {
129                            // oe.printStackTrace();
130    
131                            return null;
132                    } catch (IndexOutOfBoundsException ie)
133                    {
134                            return null;
135                    }
136            }
137    
138            /**
139             * @param string
140             * @return
141             */
142            public IPropertyDescriptor getPropertyDescriptor(String name)
143            {
144                    return findDescriptor("propertyDescriptors.{? name == '" + name + "'}[0]");
145            }
146    
147            /**
148             * @return
149             */
150            public String getPluralDisplayName()
151            {
152                    return Utils.pluralize(getDisplayName() );
153            }
154    
155            public List<IPropertyDescriptor> getPropertyDescriptors(List<String> properties) {
156                    ArrayList<IPropertyDescriptor> descriptors = new ArrayList<IPropertyDescriptor>();
157                    for (String property : properties) {
158                            descriptors.add(getPropertyDescriptor(property));
159                    }
160                    return descriptors;
161            }
162    
163            // ///////////////////////////////////////////////////////////////////////////////////////////////////////
164            // bean getters / setters
165            // ///////////////////////////////////////////////////////////////////////////////////////////////////////
166            /**
167             * @return Returns the methodDescriptors.
168             */
169            public List<IMethodDescriptor> getMethodDescriptors()
170            {
171                    return methodDescriptors;
172            }
173    
174            /**
175             * @param methodDescriptors The methodDescriptors to set.
176             */
177            public void setMethodDescriptors(List<IMethodDescriptor> methodDescriptors)
178            {
179                    this.methodDescriptors = methodDescriptors;
180            }
181    
182            /**
183             * @return Returns the propertyDescriptors.
184             */
185            public List<IPropertyDescriptor> getPropertyDescriptors()
186            {
187                    return propertyDescriptors;
188            }
189    
190            /**
191             * @param propertyDescriptors The propertyDescriptors to set.
192             */
193            public void setPropertyDescriptors(
194                    List<IPropertyDescriptor> propertyDescriptors)
195            {
196                    this.propertyDescriptors = propertyDescriptors;
197            }
198    
199            public IPropertyDescriptor getIdentifierDescriptor()
200            {
201                    String ognl = "propertyDescriptors.{? identifier}[0]";
202    
203                    return findDescriptor(ognl);
204            }
205    
206            /**
207             * @return Returns the child.
208             */
209            public boolean isChild()
210            {
211                    return child;
212            }
213    
214            /**
215             * @param child The child to set.
216             */
217            public void setChild(boolean child)
218            {
219                    this.child = child;
220            }
221    
222            @Override
223            public Object clone()
224            {
225                    return new TrailsClassDescriptor(this);
226            }
227    
228            @Override
229            public void copyFrom(IDescriptor descriptor)
230            {
231                    super.copyFrom(descriptor);
232    
233                    if (descriptor instanceof TrailsClassDescriptor)
234                    {
235    
236                            try
237                            {
238                                    BeanUtils.copyProperties(this,
239                                            (TrailsClassDescriptor) descriptor);
240                                    copyPropertyDescriptorsFrom((TrailsClassDescriptor) descriptor);
241                                    copyMethodDescriptorsFrom((TrailsClassDescriptor) descriptor);
242                            } catch (IllegalAccessException e)
243                            {
244                                    LOG.error(e.getMessage());
245                                    e.printStackTrace();
246                            } catch (InvocationTargetException e)
247                            {
248                                    LOG.error(e.getMessage());
249                                    e.printStackTrace();
250                            } catch (Exception e)
251                            {
252                                    LOG.error(e.toString());
253                                    e.printStackTrace();
254                            }
255                    }
256            }
257    
258            public boolean isAllowRemove()
259            {
260                    return allowRemove;
261            }
262    
263            public void setAllowRemove(boolean allowRemove)
264            {
265                    this.allowRemove = allowRemove;
266            }
267    
268            public boolean isAllowSave()
269            {
270                    return allowSave;
271            }
272    
273            public void setAllowSave(boolean allowSave)
274            {
275                    this.allowSave = allowSave;
276            }
277    
278            public boolean getHasCyclicRelationships()
279            {
280                    return hasCyclicRelationships;
281            }
282    
283            public void setHasCyclicRelationships(boolean hasBidirectionalRelationship)
284            {
285                    this.hasCyclicRelationships = hasBidirectionalRelationship;
286            }
287    
288            /**
289             * Added toString method to help with unit testing debugging.
290             */
291            public String toString()
292            {
293                    return "{TrailsClassDescriptor - Type: " + getType() + "}";
294            }
295    
296    }