001    /*
002     * Copyright 2010 The Kuali Foundation
003     *
004     * Licensed under the Educational Community 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
007     *
008     *      http://www.osedu.org/licenses/ECL-2.0
009     *
010     * Unless required by applicable law or agreed to in writing, software
011     * distributed under the License is distributed on an "AS IS" BASIS,
012     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013     * See the License for the specific language governing permissions and
014     * limitations under the License.
015     */
016    package org.kuali.student.mock.mojo;
017    
018    import java.util.HashSet;
019    import java.util.List;
020    import java.util.Set;
021    
022    import org.kuali.student.contract.model.MessageStructure;
023    import org.kuali.student.contract.model.ServiceContractModel;
024    import org.kuali.student.contract.model.ServiceMethod;
025    import org.kuali.student.contract.model.ServiceMethodParameter;
026    import org.kuali.student.contract.model.ServiceMethodReturnValue;
027    import org.kuali.student.contract.model.XmlType;
028    import org.kuali.student.contract.model.impl.ServiceContractModelPescXsdLoader;
029    import org.kuali.student.contract.model.util.ModelFinder;
030    import org.kuali.student.contract.model.validation.DictionaryValidationException;
031    import org.slf4j.Logger;
032    import org.slf4j.LoggerFactory;
033    
034    /**
035     *
036     * @author nwright
037     */
038    public class MockImplWriterForOneService {
039    
040        private static Logger log = LoggerFactory.getLogger(MockImplWriterForOneService.class);
041        
042        protected ServiceContractModel model;
043        protected ModelFinder finder;
044        protected String directory;
045        protected String rootPackage;
046        protected String servKey;
047        protected boolean isR1;
048    
049        public MockImplWriterForOneService(ServiceContractModel model,
050                String directory,
051                String rootPackage,
052                String servKey,
053                boolean isR1) {
054            this.model = model;
055            this.finder = new ModelFinder(model);
056            this.directory = directory;
057            this.rootPackage = rootPackage;
058            this.servKey = servKey;
059            this.isR1 = isR1;
060        }
061    
062        /**
063         * Write out the entire file
064         * @param out
065         */
066        public void write() {
067            List<ServiceMethod> methods = finder.getServiceMethodsInService(servKey);
068            if (methods.size() == 0) {
069                log.warn("No methods defined for servKey: " + servKey);
070                return;
071            }
072    
073            // the main servKey
074            log.info("Generating mock impls for " + servKey);
075            new MockImplServiceWriter(model, directory, rootPackage, servKey, methods, isR1).write();
076    
077        }
078    
079        private Set<XmlType> getXmlTypesUsedJustByService() {
080            Set<XmlType> set = new HashSet();
081            for (XmlType type : model.getXmlTypes()) {
082                if (type.getService().equalsIgnoreCase(servKey)) {
083                    if (type.getPrimitive().equalsIgnoreCase(XmlType.COMPLEX)) {
084                        set.add(type);
085                    }
086                }
087            }
088            return set;
089        }
090    
091        private Set<XmlType> getXmlTypesUsedByService(List<ServiceMethod> methods) {
092            Set<XmlType> set = new HashSet();
093            for (ServiceMethod method : methods) {
094                if (method.getReturnValue() != null) {
095                    ServiceMethodReturnValue ret = method.getReturnValue();
096                    XmlType xmlType = finder.findXmlType(stripListFromType(ret.getType()));
097                    if (xmlType == null) {
098                        throw new DictionaryValidationException("Method " + method.getService()
099                                + "." + method.getName()
100                                + "returns an unknown type, "
101                                + ret.getType());
102                    }
103                    addTypeAndAllSubTypes(set, xmlType);
104                }
105                for (ServiceMethodParameter param : method.getParameters()) {
106                    XmlType xmlType = finder.findXmlType(stripListFromType(param.getType()));
107                    if (xmlType == null) {
108                        throw new DictionaryValidationException("Parameter "
109                                + method.getService() + "."
110                                + method.getName() + "."
111                                + param.getName()
112                                + "has an unknown type, "
113                                + param.getType());
114                    }
115                    addTypeAndAllSubTypes(set, xmlType);
116                }
117            }
118            return set;
119        }
120    
121        private void addTypeAndAllSubTypes(Set<XmlType> set, XmlType xmlType) {
122            if (xmlType.getPrimitive().equalsIgnoreCase(XmlType.COMPLEX)) {
123                if (set.add(xmlType)) {
124                    addXmlTypesUsedByMessageStructure(set, xmlType);
125                }
126            }
127        }
128    
129        private String stripListFromType(String type) {
130            if (type.endsWith("List")) {
131                type = type.substring(0, type.length() - "List".length());
132            }
133            return type;
134        }
135    
136        private void addXmlTypesUsedByMessageStructure(Set<XmlType> set,
137                XmlType xmlType) {
138            ModelFinder finder = new ModelFinder(model);
139            for (MessageStructure ms : finder.findMessageStructures(xmlType.getName())) {
140                XmlType subType = finder.findXmlType(stripListFromType(ms.getType()));
141                if (subType == null) {
142                    throw new DictionaryValidationException("MessageStructure field "
143                            + ms.getId()
144                            + " has an unknown type, "
145                            + ms.getType());
146                }
147                addTypeAndAllSubTypes(set, subType);
148            }
149        }
150    }