001    package railo.runtime.component;
002    
003    import java.util.Iterator;
004    
005    import org.objectweb.asm.Type;
006    
007    import railo.commons.lang.StringUtil;
008    import railo.runtime.Component;
009    import railo.runtime.converter.ConverterException;
010    import railo.runtime.converter.ScriptConverter;
011    import railo.runtime.exp.PageException;
012    import railo.runtime.op.Caster;
013    import railo.runtime.op.Duplicator;
014    import railo.runtime.type.Collection;
015    import railo.runtime.type.KeyImpl;
016    import railo.runtime.type.Struct;
017    import railo.runtime.type.StructImpl;
018    import railo.runtime.type.util.StructUtil;
019    import railo.transformer.bytecode.util.ASMProperty;
020    import railo.transformer.bytecode.util.ASMUtil;
021    
022    /**
023     * FUTURE add a interface to public interface
024     */
025    public final class Property extends MemberSupport implements ASMProperty {
026        
027    
028            private static final Collection.Key PERSITENT = KeyImpl.intern("persistent");
029            
030            private String type="any";
031            private String name;
032            private boolean required;
033            private boolean setter=true;
034            private boolean getter=true;
035            
036    
037            private String _default;
038            private String displayname="";
039            private String hint="";
040            private Struct dynAttrs=new StructImpl();
041            private Struct metadata;
042    
043            private String ownerName;
044            
045            public Property() {
046                    super(Component.ACCESS_REMOTE);
047            }
048    
049            /**
050             * @return the _default
051             */
052            public String getDefault() {
053                    return _default;
054            }
055    
056            /**
057             * @param _default the _default to set
058             */
059            public void setDefault(String _default) {
060                    this._default = _default;
061            }
062    
063            /**
064             * @return the displayname
065             */
066            public String getDisplayname() {
067                    return displayname;
068            }
069    
070            /**
071             * @param displayname the displayname to set
072             */
073            public void setDisplayname(String displayname) {
074                    this.displayname = displayname;
075            }
076    
077            /**
078             * @return the hint
079             */
080            public String getHint() {
081                    return hint;
082            }
083    
084            /**
085             * @param hint the hint to set
086             */
087            public void setHint(String hint) {
088                    this.hint = hint;
089            }
090    
091            /**
092             * @return the name
093             */
094            public String getName() {
095                    return name;
096            }
097    
098            /**
099             * @param name the name to set
100             */
101            public void setName(String name) {
102                    this.name = name;
103            }
104    
105            /**
106             * @return the required
107             */
108            public boolean isRequired() {
109                    return required;
110            }
111    
112            /**
113             * @param required the required to set
114             */
115            public void setRequired(boolean required) {
116                    this.required = required;
117            }
118    
119            /**
120             * @return the type
121             */
122            public String getType() {
123                    return type;
124            }
125    
126            /**
127             * @param type the type to set
128             */
129            public void setType(String type) {
130                    this.type = type;
131            }
132    
133            /**
134             *
135             * @see railo.runtime.component.Member#getValue()
136             */
137            public Object getValue() {
138                    return _default;
139            }
140    
141            /**
142             *
143             * @throws PageException 
144             * @see railo.transformer.bytecode.util.ASMProperty#getASMType()
145             */
146            public Type getASMType() throws PageException {
147                    return ASMUtil.toType(getType(), true);
148            }
149            
150            /**
151             * @return the setter
152             */
153            public boolean getSetter() {
154                    return setter;
155            }
156    
157            /**
158             * @param setter the setter to set
159             */
160            public void setSetter(boolean setter) {
161                    this.setter = setter;
162            }
163    
164            /**
165             * @return the getter
166             */
167            public boolean getGetter() {
168                    return getter;
169            }
170    
171            /**
172             * @param getter the getter to set
173             */
174            public void setGetter(boolean getter) {
175                    this.getter = getter;
176            }
177            
178            
179    
180            public Object getMetaData() {
181                    Struct sct=new StructImpl();
182                    Iterator it;
183                    Object key;
184                    
185                    // meta 
186                    if(metadata!=null)
187                            StructUtil.copy(metadata, sct, true);
188                    
189                    sct.setEL(KeyImpl.NAME,name);
190                    if(!StringUtil.isEmpty(hint,true))sct.setEL(KeyImpl.HINT,hint);
191                    if(!StringUtil.isEmpty(displayname,true))sct.setEL("displayname",displayname);
192                    if(!StringUtil.isEmpty(type,true))sct.setEL(KeyImpl.TYPE,type);
193                    
194                    // dyn attributes
195    
196                    StructUtil.copy(dynAttrs, sct, true);
197                    
198                    return sct;
199            }
200    
201            public Struct getDynamicAttributes() {
202                    return dynAttrs;
203            }
204            public Struct getMeta() {
205                    if(metadata==null) metadata=new StructImpl();
206                    return metadata;
207            }
208    
209            /**
210             * @see railo.transformer.bytecode.util.ASMProperty#getClazz()
211             */
212            public Class getClazz() {
213                    return null;
214            }
215    
216            public boolean isPeristent() {
217                    return Caster.toBooleanValue(dynAttrs.get(PERSITENT,Boolean.TRUE),true);
218            }
219    
220            public void setOwnerName(String ownerName) {
221                    this.ownerName=ownerName;
222            }
223            public String getOwnerName() {
224                    return ownerName;
225            }
226    
227            
228            
229            /**
230             *
231             * @see java.lang.Object#toString()
232             */
233            public String toString() {
234                    String strDynAttrs="";
235                    try{
236                    strDynAttrs=new ScriptConverter().serialize(dynAttrs);
237                    }
238                    catch(ConverterException ce){}
239                    
240                    return "default:"+this._default+";displayname:"+this.displayname+";hint:"+this.hint+
241                    ";name:"+this.name+";type:"+this.type+";ownerName:"+ownerName+";attrs:"+strDynAttrs+";";
242            }
243            
244            public boolean equals(Object obj) {
245                    if(this == obj) return true;
246                    if(!(obj instanceof Property)) return false;
247                    Property other=(Property)obj;
248                    
249                    return toString().equals(other.toString());
250            }
251    
252            public Object duplicate(boolean deepCopy) {
253                    Property other = new Property();
254                    other._default=_default;
255                    other.displayname=displayname;
256                    other.getter=getter;
257                    other.hint=hint;
258                    other.dynAttrs=deepCopy?(Struct) Duplicator.duplicate(dynAttrs,deepCopy):dynAttrs;
259                    other.name=name;
260                    other.ownerName=ownerName;
261                    other.required=required;
262                    other.setter=setter;
263                    other.type=type;
264                    
265                    return other;
266            }
267    }