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.util;
27
28import com.sun.tools.internal.ws.processor.model.*;
29import com.sun.tools.internal.ws.processor.model.java.JavaInterface;
30import com.sun.tools.internal.ws.processor.model.jaxb.JAXBType;
31import com.sun.tools.internal.ws.processor.model.jaxb.JAXBTypeVisitor;
32import com.sun.tools.internal.ws.processor.model.jaxb.RpcLitStructure;
33
34import javax.xml.namespace.QName;
35import java.util.HashSet;
36import java.util.Iterator;
37import java.util.Set;
38
39/**
40 * This class writes out a Model as an XML document.
41 *
42 * @author WS Development Team
43 */
44public class ClassNameCollector extends ExtendedModelVisitor
45    implements JAXBTypeVisitor {
46
47    public ClassNameCollector() {
48    }
49
50    public void process(Model model) {
51        try {
52            _allClassNames = new HashSet();
53            _exceptions = new HashSet();
54            _wsdlBindingNames = new HashSet();
55            _conflictingClassNames = new HashSet();
56            _seiClassNames = new HashSet<String>();
57            _jaxbGeneratedClassNames = new HashSet<String>();
58            _exceptionClassNames = new HashSet<String>();
59            _portTypeNames = new HashSet<QName>();
60            visit(model);
61        } catch (Exception e) {
62            e.printStackTrace();
63            // fail silently
64        } finally {
65            _allClassNames = null;
66            _exceptions = null;
67        }
68    }
69
70    public Set getConflictingClassNames() {
71        return _conflictingClassNames;
72    }
73
74    protected void postVisit(Model model) throws Exception {
75        for (Iterator iter = model.getExtraTypes(); iter.hasNext();) {
76            visitType((AbstractType)iter.next());
77        }
78    }
79
80    protected void preVisit(Service service) throws Exception {
81        registerClassName(
82            ((JavaInterface)service.getJavaInterface()).getName());
83        // We don't generate Impl classes, commenting it out.
84        // Otherwise, it would cause naming conflicts
85        //registerClassName(
86        //    ((JavaInterface)service.getJavaInterface()).getImpl());
87    }
88
89    protected void processPort11x(Port port){
90        QName wsdlBindingName = (QName) port.getProperty(
91            ModelProperties.PROPERTY_WSDL_BINDING_NAME);
92        if (!_wsdlBindingNames.contains(wsdlBindingName)) {
93
94            // multiple ports can share a binding without causing a conflict
95            registerClassName(port.getJavaInterface().getName());
96        }
97        registerClassName((String) port.getProperty(
98            ModelProperties.PROPERTY_STUB_CLASS_NAME));
99        registerClassName((String) port.getProperty(
100            ModelProperties.PROPERTY_TIE_CLASS_NAME));
101    }
102
103    protected void preVisit(Port port) throws Exception {
104        QName portTypeName = (QName)port.getProperty(ModelProperties.PROPERTY_WSDL_PORT_TYPE_NAME);
105        if(_portTypeNames.contains(portTypeName))
106            return;
107
108        //in 2.0, stub/tie class are binding agnostic so they should be per port, that is multiple
109        // bindings can share the same port
110
111        addSEIClassName(port.getJavaInterface().getName());
112    }
113
114    private void addSEIClassName(String s) {
115        _seiClassNames.add(s);
116        registerClassName(s);
117    }
118
119    protected void postVisit(Port port) throws Exception {
120        QName wsdlBindingName = (QName) port.getProperty(
121            ModelProperties.PROPERTY_WSDL_BINDING_NAME);
122        if (!_wsdlBindingNames.contains(wsdlBindingName)) {
123            _wsdlBindingNames.add(wsdlBindingName);
124        }
125
126        QName portTypeName = (QName)port.getProperty(ModelProperties.PROPERTY_WSDL_PORT_TYPE_NAME);
127        if(!_portTypeNames.contains(portTypeName)){
128            _portTypeNames.add(portTypeName);
129        }
130    }
131
132    protected boolean shouldVisit(Port port) {
133        QName wsdlBindingName = (QName) port.getProperty(
134            ModelProperties.PROPERTY_WSDL_BINDING_NAME);
135        return !_wsdlBindingNames.contains(wsdlBindingName);
136    }
137
138    protected void preVisit(Fault fault) throws Exception {
139        if (!_exceptions.contains(fault.getJavaException())) {
140
141            /* the same exception can be used in several faults, but that
142             * doesn't mean that there is a conflict
143             */
144            _exceptions.add(fault.getJavaException());
145            addExceptionClassName(fault.getJavaException().getName());
146
147            for (Iterator iter = fault.getSubfaults();
148                iter != null && iter.hasNext();) {
149
150                Fault subfault = (Fault) iter.next();
151                preVisit(subfault);
152            }
153        }
154    }
155
156    private void addExceptionClassName(String name) {
157        if(_allClassNames.contains(name))
158            _exceptionClassNames.add(name);
159        registerClassName(name);
160        //To change body of created methods use File | Settings | File Templates.
161    }
162
163    protected void visitBodyBlock(Block block) throws Exception {
164        visitBlock(block);
165    }
166
167    protected void visitHeaderBlock(Block block) throws Exception {
168        visitBlock(block);
169    }
170
171    protected void visitFaultBlock(Block block) throws Exception {
172    }
173
174    protected void visitBlock(Block block) throws Exception {
175        visitType(block.getType());
176    }
177
178    protected void visit(Parameter parameter) throws Exception {
179        visitType(parameter.getType());
180    }
181
182    private void visitType(AbstractType type) throws Exception {
183        if (type != null) {
184            if (type instanceof JAXBType)
185                visitType((JAXBType)type);
186            else if (type instanceof RpcLitStructure)
187                visitType((RpcLitStructure)type);
188        }
189    }
190
191
192    private void visitType(JAXBType type) throws Exception {
193        type.accept(this);
194    }
195
196    private void visitType(RpcLitStructure type) throws Exception {
197        type.accept(this);
198    }
199    private void registerClassName(String name) {
200        if (name == null || name.equals("")) {
201            return;
202        }
203        if (_allClassNames.contains(name)) {
204            _conflictingClassNames.add(name);
205        } else {
206            _allClassNames.add(name);
207        }
208    }
209
210    public Set<String> getSeiClassNames() {
211        return _seiClassNames;
212    }
213
214    private Set<String> _seiClassNames;
215
216    public Set<String> getJaxbGeneratedClassNames() {
217        return _jaxbGeneratedClassNames;
218    }
219
220    private Set<String> _jaxbGeneratedClassNames;
221
222
223    public Set<String> getExceptionClassNames() {
224        return _exceptionClassNames;
225    }
226
227    private Set<String> _exceptionClassNames;
228    boolean doneVisitingJAXBModel = false;
229    public void visit(JAXBType type) throws Exception {
230        if(!doneVisitingJAXBModel && type.getJaxbModel() != null){
231            Set<String> classNames = type.getJaxbModel().getGeneratedClassNames();
232            for(String className : classNames){
233                addJAXBGeneratedClassName(className);
234            }
235            doneVisitingJAXBModel = true;
236        }
237    }
238
239    public void visit(RpcLitStructure type) throws Exception {
240        if(!doneVisitingJAXBModel){
241            Set<String> classNames = type.getJaxbModel().getGeneratedClassNames();
242            for(String className : classNames){
243                addJAXBGeneratedClassName(className);
244            }
245            doneVisitingJAXBModel = true;
246        }
247    }
248
249
250    private void addJAXBGeneratedClassName(String name) {
251        _jaxbGeneratedClassNames.add(name);
252        registerClassName(name);
253    }
254
255    private Set _allClassNames;
256    private Set _exceptions;
257    private Set _wsdlBindingNames;
258    private Set _conflictingClassNames;
259    private Set<QName> _portTypeNames;
260}
261