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.JBlock; 31import com.sun.codemodel.internal.JClass; 32import com.sun.codemodel.internal.JClassAlreadyExistsException; 33import com.sun.codemodel.internal.JDefinedClass; 34import com.sun.codemodel.internal.JDocComment; 35import com.sun.codemodel.internal.JExpr; 36import com.sun.codemodel.internal.JFieldRef; 37import com.sun.codemodel.internal.JFieldVar; 38import com.sun.codemodel.internal.JMethod; 39import com.sun.codemodel.internal.JMod; 40import com.sun.codemodel.internal.JType; 41import com.sun.codemodel.internal.JVar; 42import com.sun.tools.internal.ws.processor.model.Fault; 43import com.sun.tools.internal.ws.processor.model.Model; 44import com.sun.tools.internal.ws.wscompile.ErrorReceiver; 45import com.sun.tools.internal.ws.wscompile.WsimportOptions; 46 47import javax.xml.ws.WebFault; 48import java.util.HashMap; 49import java.util.Map; 50 51/** 52 * 53 * @author WS Development Team 54 */ 55public class CustomExceptionGenerator extends GeneratorBase { 56 private Map<String, JClass> faults = new HashMap<String, JClass>(); 57 58 public static void generate(Model model, 59 WsimportOptions options, 60 ErrorReceiver receiver){ 61 CustomExceptionGenerator exceptionGen = new CustomExceptionGenerator(); 62 exceptionGen.init(model, options, receiver); 63 exceptionGen.doGeneration(); 64 } 65 66 public GeneratorBase getGenerator(Model model, WsimportOptions options, ErrorReceiver receiver) { 67 GeneratorBase g = new CustomExceptionGenerator(); 68 g.init(model, options, receiver); 69 return g; 70 } 71 72 @Override 73 public void visit(Fault fault) throws Exception { 74 if (isRegistered(fault)) 75 return; 76 registerFault(fault); 77 } 78 79 private boolean isRegistered(Fault fault) { 80 if(faults.keySet().contains(fault.getJavaException().getName())){ 81 fault.setExceptionClass(faults.get(fault.getJavaException().getName())); 82 return true; 83 } 84 return false; 85 } 86 87 private void registerFault(Fault fault) { 88 try { 89 write(fault); 90 faults.put(fault.getJavaException().getName(), fault.getExceptionClass()); 91 } catch (JClassAlreadyExistsException e) { 92 throw new GeneratorException("generator.nestedGeneratorError",e); 93 } 94 } 95 96 private void write(Fault fault) throws JClassAlreadyExistsException { 97 String className = Names.customExceptionClassName(fault); 98 99 JDefinedClass cls = cm._class(className, ClassType.CLASS); 100 JDocComment comment = cls.javadoc(); 101 if(fault.getJavaDoc() != null){ 102 comment.add(fault.getJavaDoc()); 103 comment.add("\n\n"); 104 } 105 106 for (String doc : getJAXWSClassComment()) { 107 comment.add(doc); 108 } 109 110 cls._extends(java.lang.Exception.class); 111 112 //@WebFault 113 JAnnotationUse faultAnn = cls.annotate(WebFault.class); 114 faultAnn.param("name", fault.getBlock().getName().getLocalPart()); 115 faultAnn.param("targetNamespace", fault.getBlock().getName().getNamespaceURI()); 116 117 JType faultBean = fault.getBlock().getType().getJavaType().getType().getType(); 118 119 //faultInfo filed 120 JFieldVar fi = cls.field(JMod.PRIVATE, faultBean, "faultInfo"); 121 122 //add jaxb annotations 123 fault.getBlock().getType().getJavaType().getType().annotate(fi); 124 125 fi.javadoc().add("Java type that goes as soapenv:Fault detail element."); 126 JFieldRef fr = JExpr.ref(JExpr._this(), fi); 127 128 //Constructor 129 JMethod constrc1 = cls.constructor(JMod.PUBLIC); 130 JVar var1 = constrc1.param(String.class, "message"); 131 JVar var2 = constrc1.param(faultBean, "faultInfo"); 132 constrc1.javadoc().addParam(var1); 133 constrc1.javadoc().addParam(var2); 134 JBlock cb1 = constrc1.body(); 135 cb1.invoke("super").arg(var1); 136 137 cb1.assign(fr, var2); 138 139 //constructor with Throwable 140 JMethod constrc2 = cls.constructor(JMod.PUBLIC); 141 var1 = constrc2.param(String.class, "message"); 142 var2 = constrc2.param(faultBean, "faultInfo"); 143 JVar var3 = constrc2.param(Throwable.class, "cause"); 144 constrc2.javadoc().addParam(var1); 145 constrc2.javadoc().addParam(var2); 146 constrc2.javadoc().addParam(var3); 147 JBlock cb2 = constrc2.body(); 148 cb2.invoke("super").arg(var1).arg(var3); 149 cb2.assign(fr, var2); 150 151 152 //getFaultInfo() method 153 JMethod fim = cls.method(JMod.PUBLIC, faultBean, "getFaultInfo"); 154 fim.javadoc().addReturn().add("returns fault bean: "+faultBean.fullName()); 155 JBlock fib = fim.body(); 156 fib._return(fi); 157 fault.setExceptionClass(cls); 158 159 } 160} 161