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.tynamo.descriptor;
013    
014    import ognl.Ognl;
015    import ognl.OgnlException;
016    import org.apache.commons.beanutils.BeanUtils;
017    
018    import java.lang.reflect.InvocationTargetException;
019    import java.util.ArrayList;
020    import java.util.List;
021    
022    
023    /**
024     * This represents all the Tynamo metadata for a single class.
025     */
026    public class TynamoClassDescriptorImpl extends TynamoDescriptor implements TynamoClassDescriptor
027    {
028            private List<TynamoPropertyDescriptor> propertyDescriptors = new ArrayList<TynamoPropertyDescriptor>();
029    
030            private List<IMethodDescriptor> methodDescriptors = new ArrayList<IMethodDescriptor>();
031    
032            // private BeanDescriptor beanDescriptor;
033            private boolean child;
034    
035            boolean hasCyclicRelationships;
036    
037            boolean allowRemove = true;
038    
039            boolean allowSave = true;
040    
041            /**
042             * This is a copy constructor. These need to be clonable for the security
043             * aspect to be able to copy them, so if new properties are added they
044             * should be added here too.
045             */
046            public TynamoClassDescriptorImpl(TynamoClassDescriptor descriptor)
047            {
048                    super(descriptor);
049                    copyPropertyDescriptorsFrom(descriptor);
050                    copyMethodDescriptorsFrom(descriptor);
051            }
052    
053            public TynamoClassDescriptorImpl(Class beanType)
054            {
055                    super(beanType);
056            }
057    
058            /**
059             * @param dto
060             */
061            public TynamoClassDescriptorImpl(TynamoClassDescriptorImpl dto)
062            {
063                    super(dto);
064    
065                    try
066                    {
067                            BeanUtils.copyProperties(this, dto);
068                    } catch (IllegalAccessException e)
069                    {
070                            LOG.error(e.getMessage());
071                            e.printStackTrace();
072                    } catch (InvocationTargetException e)
073                    {
074                            LOG.error(e.getMessage());
075                            e.printStackTrace();
076                    } catch (Exception e)
077                    {
078                            LOG.error(e.toString());
079                            e.printStackTrace();
080                    }
081            }
082    
083            private void copyMethodDescriptorsFrom(TynamoClassDescriptor descriptor)
084            {
085                    for (IMethodDescriptor methodDescriptor : descriptor.getMethodDescriptors())
086                    {
087                            getMethodDescriptors().add(IMethodDescriptor.class.cast(methodDescriptor.clone()));
088                    }
089            }
090    
091            protected void copyPropertyDescriptorsFrom(TynamoClassDescriptor descriptor)
092            {
093                    for (TynamoPropertyDescriptor propertyDescriptor : descriptor.getPropertyDescriptors())
094                    {
095                            getPropertyDescriptors().add(TynamoPropertyDescriptor.class.cast(propertyDescriptor.clone()));
096                    }
097            }
098    
099            /**
100             * @param ognl
101             * @return
102             */
103            private TynamoPropertyDescriptor findDescriptor(String ognl)
104            {
105                    try
106                    {
107                            return (TynamoPropertyDescriptor) Ognl.getValue(ognl, this);
108                    } catch (OgnlException oe)
109                    {
110                            // oe.printStackTrace();
111    
112                            return null;
113                    } catch (IndexOutOfBoundsException ie)
114                    {
115                            return null;
116                    }
117            }
118    
119            /**
120             * @param string
121             * @return
122             */
123            public TynamoPropertyDescriptor getPropertyDescriptor(String name)
124            {
125                    return findDescriptor("propertyDescriptors.{? name == '" + name + "'}[0]");
126            }
127    
128            public List<TynamoPropertyDescriptor> getPropertyDescriptors(List<String> properties)
129            {
130                    ArrayList<TynamoPropertyDescriptor> descriptors = new ArrayList<TynamoPropertyDescriptor>();
131                    for (String property : properties)
132                    {
133                            descriptors.add(getPropertyDescriptor(property));
134                    }
135                    return descriptors;
136            }
137    
138            /**
139             * @return Returns the methodDescriptors.
140             */
141            public List<IMethodDescriptor> getMethodDescriptors()
142            {
143                    return methodDescriptors;
144            }
145    
146            /**
147             * @param methodDescriptors The methodDescriptors to set.
148             */
149            public void setMethodDescriptors(List<IMethodDescriptor> methodDescriptors)
150            {
151                    this.methodDescriptors = methodDescriptors;
152            }
153    
154            /**
155             * @return Returns the propertyDescriptors.
156             */
157            public List<TynamoPropertyDescriptor> getPropertyDescriptors()
158            {
159                    return propertyDescriptors;
160            }
161    
162            /**
163             * @param propertyDescriptors The propertyDescriptors to set.
164             */
165            public void setPropertyDescriptors(List<TynamoPropertyDescriptor> propertyDescriptors)
166            {
167                    this.propertyDescriptors = propertyDescriptors;
168            }
169    
170            public TynamoPropertyDescriptor getIdentifierDescriptor()
171            {
172                    String ognl = "propertyDescriptors.{? identifier}[0]";
173    
174                    return findDescriptor(ognl);
175            }
176    
177            /**
178             * @return Returns the child.
179             */
180            public boolean isChild()
181            {
182                    return child;
183            }
184    
185            /**
186             * @param child The child to set.
187             */
188            public void setChild(boolean child)
189            {
190                    this.child = child;
191            }
192    
193            @Override
194            public Object clone()
195            {
196                    return new TynamoClassDescriptorImpl(this);
197            }
198    
199            @Override
200            public void copyFrom(Descriptor descriptor)
201            {
202                    super.copyFrom(descriptor);
203    
204                    if (descriptor instanceof TynamoClassDescriptorImpl)
205                    {
206    
207                            try
208                            {
209                                    BeanUtils.copyProperties(this, (TynamoClassDescriptorImpl) descriptor);
210                                    copyPropertyDescriptorsFrom((TynamoClassDescriptorImpl) descriptor);
211                                    copyMethodDescriptorsFrom((TynamoClassDescriptorImpl) descriptor);
212                            } catch (IllegalAccessException e)
213                            {
214                                    LOG.error(e.getMessage());
215                                    e.printStackTrace();
216                            } catch (InvocationTargetException e)
217                            {
218                                    LOG.error(e.getMessage());
219                                    e.printStackTrace();
220                            } catch (Exception e)
221                            {
222                                    LOG.error(e.toString());
223                                    e.printStackTrace();
224                            }
225                    }
226            }
227    
228            public boolean isAllowRemove()
229            {
230                    return allowRemove;
231            }
232    
233            public void setAllowRemove(boolean allowRemove)
234            {
235                    this.allowRemove = allowRemove;
236            }
237    
238            public boolean isAllowSave()
239            {
240                    return allowSave;
241            }
242    
243            public void setAllowSave(boolean allowSave)
244            {
245                    this.allowSave = allowSave;
246            }
247    
248            public boolean getHasCyclicRelationships()
249            {
250                    return hasCyclicRelationships;
251            }
252    
253            public void setHasCyclicRelationships(boolean hasBidirectionalRelationship)
254            {
255                    this.hasCyclicRelationships = hasBidirectionalRelationship;
256            }
257    
258            /**
259             * Added toString method to help with unit testing debugging.
260             */
261            public String toString()
262            {
263                    return "{TynamoClassDescriptor - Type: " + getBeanType() + "}";
264            }
265    
266    }