001/**
002 *
003 * Copyright (c) 2014, the Railo Company Ltd. All rights reserved.
004 *
005 * This library is free software; you can redistribute it and/or
006 * modify it under the terms of the GNU Lesser General Public
007 * License as published by the Free Software Foundation; either 
008 * version 2.1 of the License, or (at your option) any later version.
009 * 
010 * This library is distributed in the hope that it will be useful,
011 * but WITHOUT ANY WARRANTY; without even the implied warranty of
012 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
013 * Lesser General Public License for more details.
014 * 
015 * You should have received a copy of the GNU Lesser General Public 
016 * License along with this library.  If not, see <http://www.gnu.org/licenses/>.
017 * 
018 **/
019package lucee.runtime.type.util;
020
021import lucee.commons.lang.StringUtil;
022import lucee.runtime.Component;
023import lucee.runtime.ComponentImpl;
024import lucee.runtime.component.Member;
025import lucee.runtime.component.Property;
026import lucee.runtime.exp.PageException;
027import lucee.runtime.op.Caster;
028import lucee.runtime.type.Collection;
029import lucee.runtime.type.Collection.Key;
030import lucee.runtime.type.KeyImpl;
031import lucee.runtime.type.UDF;
032import lucee.runtime.type.UDFAddProperty;
033import lucee.runtime.type.UDFGetterProperty;
034import lucee.runtime.type.UDFHasProperty;
035import lucee.runtime.type.UDFRemoveProperty;
036import lucee.runtime.type.UDFSetterProperty;
037
038public class PropertyFactory {
039
040        public static final Collection.Key SINGULAR_NAME = KeyImpl.intern("singularName");
041        public static final Key FIELD_TYPE = KeyConstants._fieldtype;
042
043        
044        public static void createPropertyUDFs(ComponentImpl comp, Property property) throws PageException {
045                // getter
046                if(property.getGetter()){
047                        PropertyFactory.addGet(comp,property);
048                }
049                // setter
050                if(property.getSetter()){
051                        PropertyFactory.addSet(comp,property);
052                }
053
054                String fieldType = Caster.toString(property.getDynamicAttributes().get(PropertyFactory.FIELD_TYPE,null),null);
055                
056                // add
057                if(fieldType!=null) {
058                        if("one-to-many".equalsIgnoreCase(fieldType) || "many-to-many".equalsIgnoreCase(fieldType)) {
059                                PropertyFactory.addHas(comp,property);
060                                PropertyFactory.addAdd(comp,property);
061                                PropertyFactory.addRemove(comp,property);
062                        }
063                        else if("one-to-one".equalsIgnoreCase(fieldType) || "many-to-one".equalsIgnoreCase(fieldType)) {
064                                PropertyFactory.addHas(comp,property);
065                        }
066                }
067        }
068        
069        
070        public static void addGet(ComponentImpl comp, Property prop) {
071                Member m = comp.getMember(Component.ACCESS_PRIVATE,KeyImpl.getInstance("get"+prop.getName()),true,false);
072                if(!(m instanceof UDF)){
073                        UDF udf = new UDFGetterProperty(comp,prop);
074                        comp.registerUDF(udf.getFunctionName(), udf);
075                }
076        }
077
078        public static void addSet(ComponentImpl comp, Property prop) throws PageException {
079                Member m = comp.getMember(Component.ACCESS_PRIVATE,KeyImpl.getInstance("set"+prop.getName()),true,false);
080                if(!(m instanceof UDF)){
081                        UDF udf = new UDFSetterProperty(comp,prop);
082                        comp.registerUDF(udf.getFunctionName(), udf);
083                }
084        }
085        
086        public static void addHas(ComponentImpl comp, Property prop) {
087                Member m = comp.getMember(Component.ACCESS_PRIVATE,KeyImpl.getInstance("has"+getSingularName(prop)),true,false);
088                if(!(m instanceof UDF)){
089                        UDF udf = new UDFHasProperty(comp,prop);
090                        comp.registerUDF(udf.getFunctionName(), udf);
091                }
092        }
093
094        public static void addAdd(ComponentImpl comp, Property prop) {
095                Member m = comp.getMember(ComponentImpl.ACCESS_PRIVATE,KeyImpl.getInstance("add"+getSingularName(prop)),true,false);
096                if(!(m instanceof UDF)){
097                        UDF udf = new UDFAddProperty(comp,prop);
098                        comp.registerUDF(udf.getFunctionName(), udf);
099                }
100        }
101
102        public static void addRemove(ComponentImpl comp, Property prop) {
103                Member m = comp.getMember(Component.ACCESS_PRIVATE,KeyImpl.getInstance("remove"+getSingularName(prop)),true,false);
104                if(!(m instanceof UDF)){
105                        UDF udf = new UDFRemoveProperty(comp,prop);
106                        comp.registerUDF(udf.getFunctionName(), udf);
107                }
108        }
109
110        public static String getSingularName(Property prop) {
111                String singularName=Caster.toString(prop.getDynamicAttributes().get(SINGULAR_NAME,null),null);
112                if(!StringUtil.isEmpty(singularName)) return singularName;
113                return prop.getName();
114        }
115        
116        public static String getType(Property prop){
117                String type = prop.getType();
118                if(StringUtil.isEmpty(type) || "any".equalsIgnoreCase(type) || "object".equalsIgnoreCase(type)){
119                        String fieldType = Caster.toString(prop.getDynamicAttributes().get(FIELD_TYPE,null),null);
120                        if("one-to-many".equalsIgnoreCase(fieldType) || "many-to-many".equalsIgnoreCase(fieldType)){
121                                return "array";
122                        }
123                        return "any";
124                }
125        return type;
126    }
127
128}