1 /* Copyright 2004 The Apache Software Foundation 2 * 3 * Licensed under the Apache License, Version 2.0 (the "License"); 4 * you may not use this file except in compliance with the License. 5 * You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software 10 * distributed under the License is distributed on an "AS IS" BASIS, 11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 * See the License for the specific language governing permissions and 13 * limitations under the License. 14 */ 15 16 package org.apache.xmlbeans.impl.config; 17 18 import org.apache.xmlbeans.XmlObject; 19 import org.apache.xmlbeans.PrePostExtension; 20 import org.apache.xmlbeans.impl.jam.JamClassLoader; 21 import org.apache.xmlbeans.impl.jam.JClass; 22 import org.apache.xmlbeans.impl.jam.JMethod; 23 import org.apache.xmlbeans.impl.xb.xmlconfig.Extensionconfig; 24 25 26 public class PrePostExtensionImpl implements PrePostExtension 27 { 28 29 private static JClass[] PARAMTYPES_PREPOST = null; //new JClass[]{int.class, XmlObject.class, QName.class, boolean.class, int.class}; 30 private static final String[] PARAMTYPES_STRING = new String[] {"int", "org.apache.xmlbeans.XmlObject", 31 "javax.xml.namespace.QName", "boolean", "int"}; 32 private static final String SIGNATURE; 33 static 34 { 35 String sig = "("; 36 for (int i = 0; i < PARAMTYPES_STRING.length; i++) 37 { 38 String t = PARAMTYPES_STRING[i]; 39 if (i!=0) 40 sig += ", "; 41 sig += t; 42 } 43 SIGNATURE = sig + ")"; 44 } 45 46 private NameSet _xbeanSet; 47 private JClass _delegateToClass; 48 private String _delegateToClassName; 49 private JMethod _preSet; 50 private JMethod _postSet; 51 52 static PrePostExtensionImpl newInstance(JamClassLoader jamLoader, NameSet xbeanSet, Extensionconfig.PrePostSet prePostXO) 53 { 54 if (prePostXO==null) 55 return null; 56 57 PrePostExtensionImpl result = new PrePostExtensionImpl(); 58 59 result._xbeanSet = xbeanSet; 60 result._delegateToClassName = prePostXO.getStaticHandler(); 61 result._delegateToClass = InterfaceExtensionImpl.validateClass(jamLoader, result._delegateToClassName, prePostXO); 62 63 if ( result._delegateToClass==null ) // no HandlerClass 64 { 65 BindingConfigImpl.warning("Handler class '" + prePostXO.getStaticHandler() + "' not found on classpath, skip validation.", prePostXO); 66 return result; 67 } 68 69 if (!result.lookAfterPreAndPost(jamLoader, prePostXO)) 70 return null; 71 72 return result; 73 } 74 75 private boolean lookAfterPreAndPost(JamClassLoader jamLoader, XmlObject loc) 76 { 77 assert _delegateToClass!=null : "Delegate to class handler expected."; 78 boolean valid = true; 79 80 initParamPrePost(jamLoader); 81 82 _preSet = InterfaceExtensionImpl.getMethod(_delegateToClass, "preSet", PARAMTYPES_PREPOST); 83 if (_preSet==null) 84 {} // not available is ok, _preSet will be null 85 86 if (_preSet!=null && !_preSet.getReturnType().equals(jamLoader.loadClass("boolean"))) 87 { 88 // just emit an warning and don't remember as a preSet 89 BindingConfigImpl.warning("Method '" + _delegateToClass.getSimpleName() + 90 ".preSet" + SIGNATURE + "' " + 91 "should return boolean to be considered for a preSet handler.", loc); 92 _preSet = null; 93 } 94 95 _postSet = InterfaceExtensionImpl.getMethod(_delegateToClass, "postSet", PARAMTYPES_PREPOST); 96 if (_postSet==null) 97 {} // not available is ok, _postSet will be null 98 99 if (_preSet==null && _postSet==null) 100 { 101 BindingConfigImpl.error("prePostSet handler specified '" + _delegateToClass.getSimpleName() + 102 "' but no preSet" + SIGNATURE + " or " + 103 "postSet" + SIGNATURE + " methods found.", loc); 104 valid = false; 105 } 106 107 return valid; 108 } 109 110 private void initParamPrePost(JamClassLoader jamLoader) 111 { 112 if (PARAMTYPES_PREPOST==null) 113 { 114 PARAMTYPES_PREPOST = new JClass[PARAMTYPES_STRING.length]; 115 for (int i = 0; i < PARAMTYPES_PREPOST.length; i++) 116 { 117 PARAMTYPES_PREPOST[i] = jamLoader.loadClass(PARAMTYPES_STRING[i]); 118 if (PARAMTYPES_PREPOST[i]==null) 119 { 120 throw new IllegalStateException("JAM should have access to the following types " + SIGNATURE); 121 } 122 } 123 } 124 } 125 126 // public methods 127 public NameSet getNameSet() 128 { 129 return _xbeanSet; 130 } 131 132 public boolean contains(String fullJavaName) 133 { 134 return _xbeanSet.contains(fullJavaName); 135 } 136 137 public boolean hasPreCall() 138 { 139 return _preSet!=null; 140 } 141 142 public boolean hasPostCall() 143 { 144 return _postSet!=null; 145 } 146 147 public String getStaticHandler() 148 { 149 return _delegateToClassName; 150 } 151 152 /** 153 * Returns the name of the handler in a form that can be put in a java source. 154 */ 155 public String getHandlerNameForJavaSource() 156 { 157 // used only in validation 158 if (_delegateToClass==null) 159 return null; 160 161 return InterfaceExtensionImpl.emitType(_delegateToClass); 162 } 163 164 boolean hasNameSetIntersection(PrePostExtensionImpl ext) 165 { 166 return !NameSet.EMPTY.equals(_xbeanSet.intersect(ext._xbeanSet)); 167 } 168 169 }