1/*
2 * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation.  Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 */
25
26package com.sun.tools.internal.ws.processor.generator;
27
28import com.sun.codemodel.internal.ClassType;
29import com.sun.codemodel.internal.JAnnotationUse;
30import com.sun.codemodel.internal.JClassAlreadyExistsException;
31import com.sun.codemodel.internal.JCodeModel;
32import com.sun.codemodel.internal.JDefinedClass;
33import com.sun.tools.internal.ws.ToolVersion;
34import com.sun.tools.internal.ws.processor.model.Block;
35import com.sun.tools.internal.ws.processor.model.Fault;
36import com.sun.tools.internal.ws.processor.model.Model;
37import com.sun.tools.internal.ws.processor.model.ModelVisitor;
38import com.sun.tools.internal.ws.processor.model.Operation;
39import com.sun.tools.internal.ws.processor.model.Parameter;
40import com.sun.tools.internal.ws.processor.model.Port;
41import com.sun.tools.internal.ws.processor.model.Request;
42import com.sun.tools.internal.ws.processor.model.Response;
43import com.sun.tools.internal.ws.processor.model.Service;
44import com.sun.tools.internal.ws.processor.util.DirectoryUtil;
45import com.sun.tools.internal.ws.processor.util.IndentingWriter;
46import com.sun.tools.internal.ws.wscompile.ErrorReceiver;
47import com.sun.tools.internal.ws.wscompile.WsimportOptions;
48import com.sun.xml.internal.ws.util.xml.XmlUtil;
49import org.w3c.dom.Element;
50import org.w3c.dom.NodeList;
51
52import javax.jws.HandlerChain;
53import javax.xml.transform.OutputKeys;
54import javax.xml.transform.Transformer;
55import javax.xml.transform.dom.DOMSource;
56import javax.xml.transform.stream.StreamResult;
57import java.io.File;
58import java.io.FileOutputStream;
59import java.io.OutputStreamWriter;
60import java.util.ArrayList;
61import java.util.Iterator;
62import java.util.List;
63import javax.annotation.processing.Filer;
64import javax.tools.FileObject;
65
66import javax.tools.StandardLocation;
67
68public abstract class GeneratorBase implements ModelVisitor {
69    private File destDir;
70    private String targetVersion;
71    protected boolean donotOverride;
72    protected JCodeModel cm;
73    protected Model model;
74    protected String wsdlLocation;
75    protected ErrorReceiver receiver;
76    protected WsimportOptions options;
77
78    protected GeneratorBase() {
79    }
80
81    public void init(Model model, WsimportOptions options, ErrorReceiver receiver){
82        this.model = model;
83        this.options = options;
84        this.destDir = options.destDir;
85        this.receiver = receiver;
86        this.wsdlLocation = options.wsdlLocation;
87        this.targetVersion = options.target.getVersion();
88        this.cm = options.getCodeModel();
89    }
90
91    public void doGeneration() {
92        try {
93            model.accept(this);
94        } catch (Exception e) {
95            receiver.error(e);
96        }
97    }
98
99    @Override
100    public void visit(Model model) throws Exception {
101        for (Service service : model.getServices()) {
102            service.accept(this);
103        }
104    }
105
106    @Override
107    public void visit(Service service) throws Exception {
108        for (Port port : service.getPorts()) {
109            port.accept(this);
110        }
111    }
112
113    @Override
114    public void visit(Port port) throws Exception {
115        for (Operation operation : port.getOperations()) {
116            operation.accept(this);
117        }
118    }
119
120    @Override
121    public void visit(Operation operation) throws Exception {
122        operation.getRequest().accept(this);
123        if (operation.getResponse() != null) {
124            operation.getResponse().accept(this);
125        }
126        Iterator faults = operation.getFaultsSet().iterator();
127        if (faults != null) {
128            Fault fault;
129            while (faults.hasNext()) {
130                fault = (Fault) faults.next();
131                fault.accept(this);
132            }
133        }
134    }
135
136    @Override
137    public void visit(Parameter param) throws Exception {}
138
139    @Override
140    public void visit(Block block) throws Exception {}
141
142    @Override
143    public void visit(Response response) throws Exception {}
144
145    @Override
146    public void visit(Request request) throws Exception {}
147
148    @Override
149    public void visit(Fault fault) throws Exception {}
150
151    public List<String> getJAXWSClassComment(){
152        return getJAXWSClassComment(targetVersion);
153    }
154
155    public static List<String> getJAXWSClassComment(String targetVersion) {
156        List<String> comments = new ArrayList<String>();
157        comments.add("This class was generated by the JAX-WS RI.\n");
158        comments.add(ToolVersion.VERSION.BUILD_VERSION+"\n");
159        comments.add("Generated source version: " + targetVersion);
160        return comments;
161    }
162
163    protected JDefinedClass getClass(String className, ClassType type) throws JClassAlreadyExistsException {
164        JDefinedClass cls;
165        try {
166            cls = cm._class(className, type);
167        } catch (JClassAlreadyExistsException e){
168            cls = cm._getClass(className);
169            if (cls == null) {
170                throw e;
171            }
172        }
173        return cls;
174    }
175
176    protected void log(String msg) {
177        if (options.verbose) {
178            System.out.println(
179                "["
180                    + Names.stripQualifier(this.getClass().getName())
181                    + ": "
182                    + msg
183                    + "]");
184        }
185    }
186
187    protected void writeHandlerConfig(String className, JDefinedClass cls, WsimportOptions options) {
188        Element e = options.getHandlerChainConfiguration();
189        if (e == null) {
190            return;
191        }
192        JAnnotationUse handlerChainAnn = cls.annotate(cm.ref(HandlerChain.class));
193        NodeList nl = e.getElementsByTagNameNS(
194            "http://java.sun.com/xml/ns/javaee", "handler-chain");
195        if(nl.getLength() > 0){
196            String fName = getHandlerConfigFileName(className);
197            handlerChainAnn.param("file", fName);
198            generateHandlerChainFile(e, className);
199        }
200    }
201
202     private String getHandlerConfigFileName(String fullName){
203        String name = Names.stripQualifier(fullName);
204        return name+"_handler.xml";
205    }
206
207    private void generateHandlerChainFile(Element hChains, String name) {
208
209        Filer filer = options.filer;
210
211        try {
212            IndentingWriter p;
213            FileObject jfo;
214            if (filer != null) {
215                jfo = filer.createResource(StandardLocation.SOURCE_OUTPUT,
216                        Names.getPackageName(name), getHandlerConfigFileName(name));
217                options.addGeneratedFile(new File(jfo.toUri()));
218                p = new IndentingWriter(new OutputStreamWriter(jfo.openOutputStream()));
219            } else { // leave for backw. compatibility now
220                String hcName = getHandlerConfigFileName(name);
221                File packageDir = DirectoryUtil.getOutputDirectoryFor(name, destDir);
222                File hcFile = new File(packageDir, hcName);
223                options.addGeneratedFile(hcFile);
224                p = new IndentingWriter(new OutputStreamWriter(new FileOutputStream(hcFile)));
225            }
226
227            Transformer it = XmlUtil.newTransformer();
228
229            it.setOutputProperty(OutputKeys.METHOD, "xml");
230            it.setOutputProperty(OutputKeys.INDENT, "yes");
231            it.setOutputProperty(
232                "{http://xml.apache.org/xslt}indent-amount",
233                "2");
234            it.setOutputProperty(OutputKeys.ENCODING, "UTF-8");
235            it.transform( new DOMSource(hChains), new StreamResult(p) );
236            p.close();
237        } catch (Exception e) {
238            throw new GeneratorException(
239                    "generator.nestedGeneratorError",
240                    e);
241        }
242    }
243
244}
245