001    /*
002      Copyright (C) 2003 Laurent Martelli <laurent@aopsys.com>
003    
004      This program is free software; you can redistribute it and/or modify
005      it under the terms of the GNU Lesser General Public License as
006      published by the Free Software Foundation; either version 2 of the
007      License, or (at your option) any later version.
008    
009      This program is distributed in the hope that it will be useful,
010      but WITHOUT ANY WARRANTY; without even the implied warranty of
011      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
012      GNU Lesser General Public License for more details.
013    
014      You should have received a copy of the GNU Lesser General Public
015      License along with this program; if not, write to the Free Software
016      Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
017      USA */
018    
019    package org.objectweb.jac.ide;
020    
021    import java.util.Collection;
022    import java.util.Vector;
023    import org.objectweb.jac.core.ObjectRepository;
024    import org.objectweb.jac.core.rtti.ClassItem;
025    import org.objectweb.jac.core.rtti.ClassRepository;
026    import org.objectweb.jac.core.rtti.FieldItem;
027    import org.objectweb.jac.core.rtti.NamingConventions;
028    import org.objectweb.jac.util.Strings;
029    
030    public class RelationRole extends Role implements Typed {
031    
032        protected static final String UNDEFINED = "<UNDEFINED END>";
033    
034        public RelationRole(Link link) {
035            super(link);
036        }
037    
038        public RelationRole() {
039        }
040    
041        String cardinality = "0-1";
042        public String getCardinality() {
043            return cardinality;
044        }
045        public void setCardinality(String cardinality) {
046            this.cardinality = cardinality;
047        }
048    
049        /**
050         * Returns the role name used for code generation
051         */
052        public String getGenerationName() {
053            if (end==null) 
054                return UNDEFINED;
055            return Strings.toUSAscii(getRoleName());
056        }
057    
058        public String getGenerationFullName() {
059            return start.getGenerationFullName()+"."+getGenerationName();
060        }
061    
062        public String getRoleName() {
063            if (name==null || name.equals("")) {
064                if (end==null) {
065                    return UNDEFINED;
066                } else {
067                    if (isMultiple()) {
068                        return NamingConventions.maybeLowerFirst(
069                            Projects.plurals.getPlural(end.getName()));
070                    } else {
071                        return NamingConventions.maybeLowerFirst(end.getName());
072                    }
073                }
074            } else {
075                return name;
076            }
077        }
078    
079        public Type getType() {
080            if (end == null) 
081                return null;
082            if (isMultiple()) {
083                if (primaryKey!=null)
084                    return Projects.types.resolveType("HashMap","java.util");
085                else
086                    return Projects.types.resolveType("Vector","java.util");
087            } else {
088                return (Type)end;
089            }
090        }
091    
092        public Type getAbstractType() {
093            if (end == null) 
094                return null;
095            if (isMultiple()) {
096                if (primaryKey!=null)
097                    return Projects.types.resolveType("Map","java.util");
098                else
099                    return Projects.types.resolveType("List","java.util");
100            } else {
101                return (Type)end;
102            }
103        }
104    
105        public boolean isMultiple() {
106            if( cardinality!=null && (
107                cardinality.equals("*") || cardinality.equals("0-*")||
108                cardinality.equals("1-*"))) {
109                return true;
110            } else {
111                return false;
112            }
113        }
114    
115        public String getPrototype() {
116            if (end==null) 
117                return UNDEFINED;
118            String role = getGenerationName();
119            String prototype = (getAbstractType().getGenerationFullName())+" "+role;
120            if (isMultiple()) {
121                return prototype+" = new "+getType().getGenerationFullName()+"()";
122            } else {
123                return prototype;
124            }
125        }
126    
127        Method adder;
128        public Method getAdder() {
129            return adder;
130        }
131        public void setAdder(Method method) {
132            this.adder = method;
133            if (method!=null)
134                method.setParent((Class)start);
135        }
136    
137        /**
138         * Initialize adder. Sets its name, parameters and return type.
139         *
140         * @param adder adder method to initialize
141         */
142        public void initAdder(Method adder) {
143            adder.setType(Projects.types.resolveType("void"));
144            adder.addParameter(new Parameter(NamingConventions.lowerFirst(end.getName()),(Type)end));
145            adder.setName(CodeGeneration.getAdderName(getGenerationName()));
146        }
147    
148        Method remover;
149        public Method getRemover() {
150            return remover;
151        }
152        public void setRemover(Method method) {
153            this.remover = method;
154            if (method!=null)
155                method.setParent((Class)start);
156        }
157        /**
158         * Initialize remover. Sets its name, parameters and return type.
159         *
160         * @param remover remover method to initialize
161         */
162        public void initRemover(Method remover) {
163            remover.setType(Projects.types.resolveType("void"));
164            remover.addParameter(new Parameter(NamingConventions.lowerFirst(end.getName()),(Type)end));
165            remover.setName(CodeGeneration.getRemoverName(getGenerationName()));
166        }
167    
168        Method clearer;
169        public Method getClearer() {
170            return clearer;
171        }
172        public void setClearer(Method method) {
173            this.clearer = method;
174            if (method!=null)
175                method.setParent((Class)start);
176        }
177        /**
178         * Initialize clearer. Sets its name, parameters and return type.
179         *
180         * @param clearer clearer method to initialize
181         */
182        public void initClearer(Method clearer) {
183            clearer.setType(Projects.types.resolveType("void"));
184            clearer.setName(CodeGeneration.getClearerName(getGenerationName()));
185        }
186    
187        Method getter;
188        public Method getGetter() {
189            return getter;
190        }
191        public void setGetter(Method method) {
192            this.getter = method;
193            if (method!=null)
194                method.setParent((Class)start);
195        }
196        /**
197         * Initialize getter. Sets its name, and return type.
198         *
199         * @param getter getter method to initialize
200         */
201        public void initGetter(Method getter) {
202            getter.setType(getAbstractType());
203            getter.setName(CodeGeneration.getGetterName(getGenerationName()));
204        }
205    
206        public boolean isNavigable() {
207            RelationLink rel = (RelationLink)link;
208            if (rel.getOrientation()==RelationLink.ORIENTATION_BOTH) {
209                return true;
210            } else {
211                if (link.getStartRole()==this) {
212                    return rel.getOrientation()==RelationLink.ORIENTATION_STRAIGHT;
213                } else {
214                    return rel.getOrientation()==RelationLink.ORIENTATION_REVERSE;
215                }
216            }
217        }
218    
219        public boolean isAggregation() {
220            RelationLink rel = (RelationLink)link;
221            return rel.isAggregation() && isStartRole();
222        }   
223    
224        /** Field or RelationRole */
225        Typed primaryKey;
226        public Typed getPrimaryKey() {
227            return primaryKey;
228        }
229        public void setPrimaryKey(Typed primaryKey) {
230            this.primaryKey = primaryKey;
231        }
232    
233        /**
234         * Returns the name of the getter method.
235         */
236        public String getRemoverName() {
237            if (remover!=null) {
238                return remover.getGenerationName();
239            } else {
240                return CodeGeneration.getRemoverName(getGenerationName());
241            }
242        }
243    
244        public Collection primaryKeyChoices() {
245            if (end==null) {
246                return new Vector(0);
247            } else {
248                Class cl = (Class)end;
249                Vector result = new Vector();
250                result.addAll(cl.getReferenceRoles());
251                result.addAll(cl.getAllFields());
252                return result;
253            }
254        }
255    
256        public Collection methodChoices() {
257            ClassItem cl = ClassRepository.get().getClass(Method.class);
258            FieldItem field = cl.getField("parent");
259            return ObjectRepository.getObjectsWhere(cl,field,null);
260        }
261    }
262