PageRenderTime 42ms CodeModel.GetById 9ms RepoModel.GetById 0ms app.codeStats 0ms

/jboss-as-7.1.1.Final/webservices/server-integration/src/main/java/org/jboss/as/webservices/parser/WSDeploymentAspectParser.java

#
Java | 390 lines | 329 code | 20 blank | 41 comment | 78 complexity | 87e0aae7e5ba191a88983e6a8f18c6ff MD5 | raw file
Possible License(s): LGPL-2.1, Apache-2.0
  1. /*
  2. * JBoss, Home of Professional Open Source.
  3. * Copyright 2011, Red Hat Middleware LLC, and individual contributors
  4. * as indicated by the @author tags. See the copyright.txt file in the
  5. * distribution for a full listing of individual contributors.
  6. *
  7. * This is free software; you can redistribute it and/or modify it
  8. * under the terms of the GNU Lesser General Public License as
  9. * published by the Free Software Foundation; either version 2.1 of
  10. * the License, or (at your option) any later version.
  11. *
  12. * This software is distributed in the hope that it will be useful,
  13. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  15. * Lesser General Public License for more details.
  16. *
  17. * You should have received a copy of the GNU Lesser General Public
  18. * License along with this software; if not, write to the Free
  19. * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
  20. * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
  21. */
  22. package org.jboss.as.webservices.parser;
  23. import static javax.xml.stream.XMLStreamConstants.END_ELEMENT;
  24. import static javax.xml.stream.XMLStreamConstants.START_ELEMENT;
  25. import static org.jboss.as.webservices.WSMessages.MESSAGES;
  26. import static org.jboss.wsf.spi.util.StAXUtils.match;
  27. import java.io.InputStream;
  28. import java.lang.reflect.Method;
  29. import java.security.AccessController;
  30. import java.security.PrivilegedAction;
  31. import java.util.LinkedList;
  32. import java.util.List;
  33. import java.util.Map;
  34. import javax.xml.stream.XMLStreamConstants;
  35. import javax.xml.stream.XMLStreamException;
  36. import javax.xml.stream.XMLStreamReader;
  37. import javax.xml.ws.WebServiceException;
  38. import org.jboss.ws.common.JavaUtils;
  39. import org.jboss.wsf.spi.deployment.DeploymentAspect;
  40. import org.jboss.wsf.spi.util.StAXUtils;
  41. /**
  42. * A parser for WS deployment aspects
  43. *
  44. * @author alessio.soldano@jboss.com
  45. * @since 18-Jan-2011
  46. *
  47. */
  48. public class WSDeploymentAspectParser {
  49. private static final String NS = "urn:jboss:ws:deployment:aspects:1.0";
  50. private static final String DEPLOYMENT_ASPECTS = "deploymentAspects";
  51. private static final String DEPLOYMENT_ASPECT = "deploymentAspect";
  52. private static final String CLASS = "class";
  53. private static final String PRIORITY = "priority";
  54. private static final String PROPERTY = "property";
  55. private static final String NAME = "name";
  56. private static final String MAP = "map";
  57. private static final String KEY_CLASS = "keyClass";
  58. private static final String VALUE_CLASS = "valueClass";
  59. private static final String ENTRY = "entry";
  60. private static final String KEY = "key";
  61. private static final String VALUE = "value";
  62. private static final String LIST = "list";
  63. private static final String ELEMENT_CLASS = "elementClass";
  64. public static List<DeploymentAspect> parse(InputStream is, ClassLoader loader) {
  65. try {
  66. XMLStreamReader xmlr = StAXUtils.createXMLStreamReader(is);
  67. return parse(xmlr, loader);
  68. } catch (Exception e) {
  69. throw new WebServiceException(e);
  70. }
  71. }
  72. public static List<DeploymentAspect> parse(XMLStreamReader reader, ClassLoader loader) throws XMLStreamException {
  73. int iterate;
  74. try {
  75. iterate = reader.nextTag();
  76. } catch (XMLStreamException e) {
  77. // skip non-tag elements
  78. iterate = reader.nextTag();
  79. }
  80. List<DeploymentAspect> deploymentAspects = null;
  81. switch (iterate) {
  82. case END_ELEMENT: {
  83. // we're done
  84. break;
  85. }
  86. case START_ELEMENT: {
  87. if (match(reader, NS, DEPLOYMENT_ASPECTS)) {
  88. deploymentAspects = parseDeploymentAspects(reader, loader);
  89. } else {
  90. throw MESSAGES.unexpectedElement(reader.getLocalName());
  91. }
  92. }
  93. }
  94. return deploymentAspects;
  95. }
  96. private static List<DeploymentAspect> parseDeploymentAspects(XMLStreamReader reader, ClassLoader loader) throws XMLStreamException {
  97. List<DeploymentAspect> deploymentAspects = new LinkedList<DeploymentAspect>();
  98. while (reader.hasNext()) {
  99. switch (reader.nextTag()) {
  100. case XMLStreamConstants.END_ELEMENT: {
  101. if (match(reader, NS, DEPLOYMENT_ASPECTS)) {
  102. return deploymentAspects;
  103. } else {
  104. throw MESSAGES.unexpectedEndTag(reader.getLocalName());
  105. }
  106. }
  107. case XMLStreamConstants.START_ELEMENT: {
  108. if (match(reader, NS, DEPLOYMENT_ASPECT)) {
  109. deploymentAspects.add(parseDeploymentAspect(reader, loader));
  110. } else {
  111. throw MESSAGES.unexpectedElement(reader.getLocalName());
  112. }
  113. }
  114. }
  115. }
  116. throw MESSAGES.unexpectedEndOfDocument();
  117. }
  118. private static DeploymentAspect parseDeploymentAspect(XMLStreamReader reader, ClassLoader loader) throws XMLStreamException {
  119. String deploymentAspectClass = reader.getAttributeValue(null, CLASS);
  120. if (deploymentAspectClass == null) {
  121. throw MESSAGES.missingDeploymentAspectClassAttribute();
  122. }
  123. DeploymentAspect deploymentAspect = null;
  124. try {
  125. @SuppressWarnings("unchecked")
  126. Class<? extends DeploymentAspect> clazz = (Class<? extends DeploymentAspect>) Class.forName(deploymentAspectClass, true, loader);
  127. ClassLoader orig = getContextClassLoader();
  128. try {
  129. setContextClassLoader(loader);
  130. deploymentAspect = clazz.newInstance();
  131. } finally {
  132. setContextClassLoader(orig);
  133. }
  134. } catch (Exception e) {
  135. throw MESSAGES.cannotInstantiateDeploymentAspect(e, deploymentAspectClass);
  136. }
  137. String priority = reader.getAttributeValue(null, PRIORITY);
  138. if (priority != null) {
  139. deploymentAspect.setRelativeOrder(Integer.parseInt(priority.trim()));
  140. }
  141. while (reader.hasNext()) {
  142. switch (reader.nextTag()) {
  143. case XMLStreamConstants.END_ELEMENT: {
  144. if (match(reader, NS, DEPLOYMENT_ASPECT)) {
  145. return deploymentAspect;
  146. } else {
  147. throw MESSAGES.unexpectedEndTag(reader.getLocalName());
  148. }
  149. }
  150. case XMLStreamConstants.START_ELEMENT: {
  151. if (match(reader, NS, PROPERTY)) {
  152. parseProperty(reader, deploymentAspect, loader);
  153. } else {
  154. throw MESSAGES.unexpectedElement(reader.getLocalName());
  155. }
  156. }
  157. }
  158. }
  159. throw MESSAGES.unexpectedEndOfDocument();
  160. }
  161. @SuppressWarnings("rawtypes")
  162. private static void parseProperty(XMLStreamReader reader, DeploymentAspect deploymentAspect, ClassLoader loader) throws XMLStreamException {
  163. Class<? extends DeploymentAspect> deploymentAspectClass = deploymentAspect.getClass();
  164. String propName = reader.getAttributeValue(null, NAME);
  165. if (propName == null) {
  166. throw MESSAGES.missingPropertyNameAttribute(deploymentAspect);
  167. }
  168. String propClass = reader.getAttributeValue(null, CLASS);
  169. if (propClass == null) {
  170. throw MESSAGES.missingPropertyClassAttribute(deploymentAspect);
  171. } else {
  172. try {
  173. if (isSupportedPropertyClass(propClass)) {
  174. Method m = selectMethod(deploymentAspectClass, propName, propClass);
  175. m.invoke(deploymentAspect, parseSimpleValue(reader, propClass));
  176. return;
  177. }
  178. } catch (Exception e) {
  179. throw new IllegalStateException(e);
  180. }
  181. }
  182. while (reader.hasNext()) {
  183. switch (reader.nextTag()) {
  184. case XMLStreamConstants.END_ELEMENT: {
  185. if (match(reader, NS, PROPERTY)) {
  186. return;
  187. } else {
  188. throw MESSAGES.unexpectedEndTag(reader.getLocalName());
  189. }
  190. }
  191. case XMLStreamConstants.START_ELEMENT: {
  192. if (match(reader, NS, MAP)) {
  193. try {
  194. Method m = selectMethod(deploymentAspectClass, propName, propClass);
  195. Map map = parseMapProperty(reader, propClass, reader.getAttributeValue(null, KEY_CLASS),
  196. reader.getAttributeValue(null, VALUE_CLASS), loader);
  197. m.invoke(deploymentAspect, map);
  198. } catch (Exception e) {
  199. throw new IllegalStateException(e);
  200. }
  201. } else if (match(reader, NS, LIST)) {
  202. try {
  203. Method m = selectMethod(deploymentAspectClass, propName, propClass);
  204. List list = parseListProperty(reader, propClass, reader.getAttributeValue(null, ELEMENT_CLASS));
  205. m.invoke(deploymentAspect, list);
  206. } catch (Exception e) {
  207. throw new IllegalStateException(e);
  208. }
  209. } else {
  210. throw MESSAGES.unexpectedElement(reader.getLocalName());
  211. }
  212. }
  213. }
  214. }
  215. throw MESSAGES.unexpectedEndOfDocument();
  216. }
  217. private static Method selectMethod(Class<?> deploymentAspectClass, String propName, String propClass) throws ClassNotFoundException {
  218. //TODO improve this (better support for primitives, edge cases, etc.)
  219. Method[] methods = deploymentAspectClass.getMethods();
  220. for (Method m : methods) {
  221. if (m.getName().equals("set" + JavaUtils.capitalize(propName))) {
  222. Class<?>[] pars = m.getParameterTypes();
  223. if (pars.length == 1 && (propClass.equals(pars[0].getName()) || (pars[0].isAssignableFrom(Class.forName(propClass))))) {
  224. return m;
  225. }
  226. }
  227. }
  228. return null;
  229. }
  230. private static boolean isSupportedPropertyClass(String propClass) {
  231. return (String.class.getName().equals(propClass) || Boolean.class.getName().equals(propClass) || Integer.class
  232. .getName().equals(propClass) || JavaUtils.isPrimitive(propClass));
  233. }
  234. private static Object parseSimpleValue(XMLStreamReader reader, String propClass) throws XMLStreamException {
  235. if (String.class.getName().equals(propClass)) {
  236. return StAXUtils.elementAsString(reader);
  237. } else if (Boolean.class.getName().equals(propClass)) {
  238. return StAXUtils.elementAsBoolean(reader);
  239. } else if (Integer.class.getName().equals(propClass)) {
  240. return StAXUtils.elementAsInt(reader);
  241. } else if (boolean.class.getName().equals(propClass)) {
  242. return StAXUtils.elementAsBoolean(reader);
  243. } else {
  244. throw MESSAGES.unsupportedPropertyClass(propClass);
  245. }
  246. }
  247. @SuppressWarnings({ "rawtypes", "unchecked" })
  248. private static List parseListProperty(XMLStreamReader reader, String propClass, String elementClass)
  249. throws XMLStreamException {
  250. List list = null;
  251. try {
  252. list = (List) Class.forName(propClass).newInstance();
  253. } catch (Exception e) {
  254. throw MESSAGES.cannotInstantiateList(e, propClass);
  255. }
  256. while (reader.hasNext()) {
  257. switch (reader.nextTag()) {
  258. case XMLStreamConstants.END_ELEMENT: {
  259. if (match(reader, NS, LIST)) {
  260. return list;
  261. } else {
  262. throw MESSAGES.unexpectedEndTag(reader.getLocalName());
  263. }
  264. }
  265. case XMLStreamConstants.START_ELEMENT: {
  266. if (match(reader, NS, VALUE)) {
  267. list.add(parseSimpleValue(reader, elementClass));
  268. } else {
  269. throw MESSAGES.unexpectedElement(reader.getLocalName());
  270. }
  271. }
  272. }
  273. }
  274. throw MESSAGES.unexpectedEndOfDocument();
  275. }
  276. @SuppressWarnings("rawtypes")
  277. private static Map parseMapProperty(XMLStreamReader reader, String propClass, String keyClass, String valueClass, ClassLoader loader)
  278. throws XMLStreamException {
  279. Map map = null;
  280. try {
  281. map = (Map) Class.forName(propClass, true, loader).newInstance();
  282. } catch (Exception e) {
  283. throw MESSAGES.cannotInstantiateMap(e, propClass);
  284. }
  285. while (reader.hasNext()) {
  286. switch (reader.nextTag()) {
  287. case XMLStreamConstants.END_ELEMENT: {
  288. if (match(reader, NS, MAP)) {
  289. return map;
  290. } else {
  291. throw MESSAGES.unexpectedEndTag(reader.getLocalName());
  292. }
  293. }
  294. case XMLStreamConstants.START_ELEMENT: {
  295. if (match(reader, NS, ENTRY)) {
  296. parseMapEntry(reader, map, keyClass, valueClass);
  297. } else {
  298. throw MESSAGES.unexpectedElement(reader.getLocalName());
  299. }
  300. }
  301. }
  302. }
  303. throw MESSAGES.unexpectedEndOfDocument();
  304. }
  305. @SuppressWarnings({ "rawtypes", "unchecked" })
  306. private static void parseMapEntry(XMLStreamReader reader, Map map, String keyClass, String valueClass)
  307. throws XMLStreamException {
  308. boolean keyStartDone = false, valueStartDone = false;
  309. Object key = null;
  310. Object value = null;
  311. while (reader.hasNext()) {
  312. switch (reader.nextTag()) {
  313. case XMLStreamConstants.END_ELEMENT: {
  314. if (match(reader, NS, ENTRY) && keyStartDone && valueStartDone) {
  315. map.put(key, value);
  316. return;
  317. } else {
  318. throw MESSAGES.unexpectedEndTag(reader.getLocalName());
  319. }
  320. }
  321. case XMLStreamConstants.START_ELEMENT: {
  322. if (match(reader, NS, KEY)) {
  323. keyStartDone = true;
  324. key = parseSimpleValue(reader, keyClass);
  325. } else if (match(reader, NS, VALUE)) {
  326. valueStartDone = true;
  327. value = parseSimpleValue(reader, valueClass);
  328. } else {
  329. throw MESSAGES.unexpectedElement(reader.getLocalName());
  330. }
  331. }
  332. }
  333. }
  334. throw MESSAGES.unexpectedEndOfDocument();
  335. }
  336. /**
  337. * Get context classloader.
  338. *
  339. * @return the current context classloader
  340. */
  341. private static ClassLoader getContextClassLoader() {
  342. SecurityManager sm = System.getSecurityManager();
  343. if (sm == null) {
  344. return Thread.currentThread().getContextClassLoader();
  345. } else {
  346. return AccessController.doPrivileged(new PrivilegedAction<ClassLoader>() {
  347. public ClassLoader run() {
  348. return Thread.currentThread().getContextClassLoader();
  349. }
  350. });
  351. }
  352. }
  353. /**
  354. * Set context classloader.
  355. *
  356. * @param classLoader the classloader
  357. */
  358. private static void setContextClassLoader(final ClassLoader classLoader) {
  359. if (System.getSecurityManager() == null) {
  360. Thread.currentThread().setContextClassLoader(classLoader);
  361. } else {
  362. AccessController.doPrivileged(new PrivilegedAction<Object>() {
  363. public Object run() {
  364. Thread.currentThread().setContextClassLoader(classLoader);
  365. return null;
  366. }
  367. });
  368. }
  369. }
  370. }