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 */
016package org.kuali.student.mock.mojo;
017
018import java.util.HashSet;
019import java.util.List;
020import java.util.Set;
021
022import org.kuali.student.contract.model.MessageStructure;
023import org.kuali.student.contract.model.ServiceContractModel;
024import org.kuali.student.contract.model.ServiceMethod;
025import org.kuali.student.contract.model.ServiceMethodParameter;
026import org.kuali.student.contract.model.ServiceMethodReturnValue;
027import org.kuali.student.contract.model.XmlType;
028import org.kuali.student.contract.model.impl.ServiceContractModelPescXsdLoader;
029import org.kuali.student.contract.model.util.ModelFinder;
030import org.kuali.student.contract.model.validation.DictionaryValidationException;
031import org.slf4j.Logger;
032import org.slf4j.LoggerFactory;
033
034/**
035 *
036 * @author nwright
037 */
038public 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}