001    /**
002     * Copyright 2004-2014 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.opensource.org/licenses/ecl2.php
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.jpa.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.util.ModelFinder;
029    import org.kuali.student.contract.model.validation.DictionaryValidationException;
030    import org.slf4j.Logger;
031    import org.slf4j.LoggerFactory;
032    
033    /**
034     *
035     * @author nwright
036     */
037    public class JpaImplWriterForOneService {
038    
039        private static final Logger log = LoggerFactory.getLogger(JpaImplWriterForOneService.class);
040        
041        protected ServiceContractModel model;
042        protected ModelFinder finder;
043        protected String directory;
044        protected String rootPackage;
045        protected String servKey;
046        protected boolean isR1;
047    
048        public JpaImplWriterForOneService(ServiceContractModel model,
049                String directory,
050                String rootPackage,
051                String servKey,
052                boolean isR1) {
053            this.model = model;
054            this.finder = new ModelFinder(model);
055            this.directory = directory;
056            this.rootPackage = rootPackage;
057            this.servKey = servKey;
058            this.isR1 = isR1;
059        }
060    
061        /**
062         * Write out the entire file
063         * @param out
064         */
065        public void write() {
066            List<ServiceMethod> methods = finder.getServiceMethodsInService(servKey);
067            if (methods.size() == 0) {
068                log.warn("No methods defined for servKey: {}", servKey);
069                return;
070            }
071    
072            // the main servKey
073            log.info("Generating jpa impls for {}", servKey);
074            new JpaImplServiceWriter(model, directory, rootPackage, servKey, methods, isR1).write();
075            
076    //        for (XmlType xmlType : getXmlTypesUsedJustByService()) {
077    //            new JpaEntityWriter(model, directory, rootPackage, servKey, methods, xmlType, isR1).write();
078    //        }
079    
080        }
081    
082        private Set<XmlType> getXmlTypesUsedJustByService() {
083            Set<XmlType> set = new HashSet();
084            for (XmlType type : model.getXmlTypes()) {
085                if (type.getService().equalsIgnoreCase(servKey)) {
086                    if (type.getPrimitive().equalsIgnoreCase(XmlType.COMPLEX)) {
087                        set.add(type);
088                    }
089                }
090            }
091            return set;
092        }
093    
094        private Set<XmlType> getXmlTypesUsedByService(List<ServiceMethod> methods) {
095            Set<XmlType> set = new HashSet();
096            for (ServiceMethod method : methods) {
097                if (method.getReturnValue() != null) {
098                    ServiceMethodReturnValue ret = method.getReturnValue();
099                    XmlType xmlType = finder.findXmlType(stripListFromType(ret.getType()));
100                    if (xmlType == null) {
101                        throw new DictionaryValidationException("Method " + method.getService()
102                                + "." + method.getName()
103                                + "returns an unknown type, "
104                                + ret.getType());
105                    }
106                    addTypeAndAllSubTypes(set, xmlType);
107                }
108                for (ServiceMethodParameter param : method.getParameters()) {
109                    XmlType xmlType = finder.findXmlType(stripListFromType(param.getType()));
110                    if (xmlType == null) {
111                        throw new DictionaryValidationException("Parameter "
112                                + method.getService() + "."
113                                + method.getName() + "."
114                                + param.getName()
115                                + "has an unknown type, "
116                                + param.getType());
117                    }
118                    addTypeAndAllSubTypes(set, xmlType);
119                }
120            }
121            return set;
122        }
123    
124        private void addTypeAndAllSubTypes(Set<XmlType> set, XmlType xmlType) {
125            if (xmlType.getPrimitive().equalsIgnoreCase(XmlType.COMPLEX)) {
126                if (set.add(xmlType)) {
127                    addXmlTypesUsedByMessageStructure(set, xmlType);
128                }
129            }
130        }
131    
132        private String stripListFromType(String type) {
133            if (type.endsWith("List")) {
134                type = type.substring(0, type.length() - "List".length());
135            }
136            return type;
137        }
138    
139        private void addXmlTypesUsedByMessageStructure(Set<XmlType> set,
140                XmlType xmlType) {
141            ModelFinder finder = new ModelFinder(model);
142            for (MessageStructure ms : finder.findMessageStructures(xmlType.getName())) {
143                XmlType subType = finder.findXmlType(stripListFromType(ms.getType()));
144                if (subType == null) {
145                    throw new DictionaryValidationException("MessageStructure field "
146                            + ms.getId()
147                            + " has an unknown type, "
148                            + ms.getType());
149                }
150                addTypeAndAllSubTypes(set, subType);
151            }
152        }
153    }