PageRenderTime 46ms CodeModel.GetById 20ms app.highlight 24ms 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 */
 22package org.jboss.as.webservices.parser;
 23
 24import static javax.xml.stream.XMLStreamConstants.END_ELEMENT;
 25import static javax.xml.stream.XMLStreamConstants.START_ELEMENT;
 26import static org.jboss.as.webservices.WSMessages.MESSAGES;
 27import static org.jboss.wsf.spi.util.StAXUtils.match;
 28
 29import java.io.InputStream;
 30import java.lang.reflect.Method;
 31import java.security.AccessController;
 32import java.security.PrivilegedAction;
 33import java.util.LinkedList;
 34import java.util.List;
 35import java.util.Map;
 36
 37import javax.xml.stream.XMLStreamConstants;
 38import javax.xml.stream.XMLStreamException;
 39import javax.xml.stream.XMLStreamReader;
 40import javax.xml.ws.WebServiceException;
 41
 42import org.jboss.ws.common.JavaUtils;
 43import org.jboss.wsf.spi.deployment.DeploymentAspect;
 44import org.jboss.wsf.spi.util.StAXUtils;
 45
 46/**
 47 * A parser for WS deployment aspects
 48 *
 49 * @author alessio.soldano@jboss.com
 50 * @since 18-Jan-2011
 51 *
 52 */
 53public class WSDeploymentAspectParser {
 54
 55    private static final String NS = "urn:jboss:ws:deployment:aspects:1.0";
 56    private static final String DEPLOYMENT_ASPECTS = "deploymentAspects";
 57    private static final String DEPLOYMENT_ASPECT = "deploymentAspect";
 58    private static final String CLASS = "class";
 59    private static final String PRIORITY = "priority";
 60    private static final String PROPERTY = "property";
 61    private static final String NAME = "name";
 62    private static final String MAP = "map";
 63    private static final String KEY_CLASS = "keyClass";
 64    private static final String VALUE_CLASS = "valueClass";
 65    private static final String ENTRY = "entry";
 66    private static final String KEY = "key";
 67    private static final String VALUE = "value";
 68    private static final String LIST = "list";
 69    private static final String ELEMENT_CLASS = "elementClass";
 70
 71    public static List<DeploymentAspect> parse(InputStream is, ClassLoader loader) {
 72        try {
 73            XMLStreamReader xmlr = StAXUtils.createXMLStreamReader(is);
 74            return parse(xmlr, loader);
 75        } catch (Exception e) {
 76            throw new WebServiceException(e);
 77        }
 78    }
 79
 80    public static List<DeploymentAspect> parse(XMLStreamReader reader, ClassLoader loader) throws XMLStreamException {
 81        int iterate;
 82        try {
 83            iterate = reader.nextTag();
 84        } catch (XMLStreamException e) {
 85            // skip non-tag elements
 86            iterate = reader.nextTag();
 87        }
 88        List<DeploymentAspect> deploymentAspects = null;
 89        switch (iterate) {
 90            case END_ELEMENT: {
 91                // we're done
 92                break;
 93            }
 94            case START_ELEMENT: {
 95
 96                if (match(reader, NS, DEPLOYMENT_ASPECTS)) {
 97                    deploymentAspects = parseDeploymentAspects(reader, loader);
 98                } else {
 99                    throw MESSAGES.unexpectedElement(reader.getLocalName());
100                }
101            }
102        }
103        return deploymentAspects;
104    }
105
106    private static List<DeploymentAspect> parseDeploymentAspects(XMLStreamReader reader, ClassLoader loader) throws XMLStreamException {
107        List<DeploymentAspect> deploymentAspects = new LinkedList<DeploymentAspect>();
108        while (reader.hasNext()) {
109            switch (reader.nextTag()) {
110                case XMLStreamConstants.END_ELEMENT: {
111                    if (match(reader, NS, DEPLOYMENT_ASPECTS)) {
112                        return deploymentAspects;
113                    } else {
114                        throw MESSAGES.unexpectedEndTag(reader.getLocalName());
115                    }
116                }
117                case XMLStreamConstants.START_ELEMENT: {
118                    if (match(reader, NS, DEPLOYMENT_ASPECT)) {
119                        deploymentAspects.add(parseDeploymentAspect(reader, loader));
120                    } else {
121                        throw MESSAGES.unexpectedElement(reader.getLocalName());
122                    }
123                }
124            }
125        }
126        throw MESSAGES.unexpectedEndOfDocument();
127    }
128
129    private static DeploymentAspect parseDeploymentAspect(XMLStreamReader reader, ClassLoader loader) throws XMLStreamException {
130        String deploymentAspectClass = reader.getAttributeValue(null, CLASS);
131        if (deploymentAspectClass == null) {
132            throw MESSAGES.missingDeploymentAspectClassAttribute();
133        }
134        DeploymentAspect deploymentAspect = null;
135        try {
136            @SuppressWarnings("unchecked")
137            Class<? extends DeploymentAspect> clazz = (Class<? extends DeploymentAspect>) Class.forName(deploymentAspectClass, true, loader);
138            ClassLoader orig = getContextClassLoader();
139            try {
140                setContextClassLoader(loader);
141                deploymentAspect = clazz.newInstance();
142            } finally {
143                setContextClassLoader(orig);
144            }
145        } catch (Exception e) {
146            throw MESSAGES.cannotInstantiateDeploymentAspect(e, deploymentAspectClass);
147        }
148        String priority = reader.getAttributeValue(null, PRIORITY);
149        if (priority != null) {
150            deploymentAspect.setRelativeOrder(Integer.parseInt(priority.trim()));
151        }
152        while (reader.hasNext()) {
153            switch (reader.nextTag()) {
154                case XMLStreamConstants.END_ELEMENT: {
155                    if (match(reader, NS, DEPLOYMENT_ASPECT)) {
156                        return deploymentAspect;
157                    } else {
158                        throw MESSAGES.unexpectedEndTag(reader.getLocalName());
159                    }
160                }
161                case XMLStreamConstants.START_ELEMENT: {
162                    if (match(reader, NS, PROPERTY)) {
163                        parseProperty(reader, deploymentAspect, loader);
164                    } else {
165                        throw MESSAGES.unexpectedElement(reader.getLocalName());
166                    }
167                }
168            }
169        }
170        throw MESSAGES.unexpectedEndOfDocument();
171    }
172
173    @SuppressWarnings("rawtypes")
174    private static void parseProperty(XMLStreamReader reader, DeploymentAspect deploymentAspect, ClassLoader loader) throws XMLStreamException {
175        Class<? extends DeploymentAspect> deploymentAspectClass = deploymentAspect.getClass();
176        String propName = reader.getAttributeValue(null, NAME);
177        if (propName == null) {
178            throw MESSAGES.missingPropertyNameAttribute(deploymentAspect);
179        }
180        String propClass = reader.getAttributeValue(null, CLASS);
181        if (propClass == null) {
182            throw MESSAGES.missingPropertyClassAttribute(deploymentAspect);
183        } else {
184            try {
185                if (isSupportedPropertyClass(propClass)) {
186                    Method m = selectMethod(deploymentAspectClass, propName, propClass);
187                    m.invoke(deploymentAspect, parseSimpleValue(reader, propClass));
188                    return;
189                }
190            } catch (Exception e) {
191                throw new IllegalStateException(e);
192            }
193        }
194        while (reader.hasNext()) {
195            switch (reader.nextTag()) {
196                case XMLStreamConstants.END_ELEMENT: {
197                    if (match(reader, NS, PROPERTY)) {
198                        return;
199                    } else {
200                        throw MESSAGES.unexpectedEndTag(reader.getLocalName());
201                    }
202                }
203                case XMLStreamConstants.START_ELEMENT: {
204                    if (match(reader, NS, MAP)) {
205                        try {
206                            Method m = selectMethod(deploymentAspectClass, propName, propClass);
207                            Map map = parseMapProperty(reader, propClass, reader.getAttributeValue(null, KEY_CLASS),
208                                    reader.getAttributeValue(null, VALUE_CLASS), loader);
209                            m.invoke(deploymentAspect, map);
210                        } catch (Exception e) {
211                            throw new IllegalStateException(e);
212                        }
213                    } else if (match(reader, NS, LIST)) {
214                        try {
215                            Method m = selectMethod(deploymentAspectClass, propName, propClass);
216                            List list = parseListProperty(reader, propClass, reader.getAttributeValue(null, ELEMENT_CLASS));
217                            m.invoke(deploymentAspect, list);
218                        } catch (Exception e) {
219                            throw new IllegalStateException(e);
220                        }
221                    } else {
222                        throw MESSAGES.unexpectedElement(reader.getLocalName());
223                    }
224                }
225            }
226        }
227        throw MESSAGES.unexpectedEndOfDocument();
228    }
229
230    private static Method selectMethod(Class<?> deploymentAspectClass, String propName, String propClass) throws ClassNotFoundException {
231        //TODO improve this (better support for primitives, edge cases, etc.)
232        Method[] methods = deploymentAspectClass.getMethods();
233        for (Method m : methods) {
234            if (m.getName().equals("set" + JavaUtils.capitalize(propName))) {
235                Class<?>[] pars = m.getParameterTypes();
236                if (pars.length == 1 && (propClass.equals(pars[0].getName()) || (pars[0].isAssignableFrom(Class.forName(propClass))))) {
237                    return m;
238                }
239            }
240        }
241        return null;
242    }
243
244    private static boolean isSupportedPropertyClass(String propClass) {
245        return (String.class.getName().equals(propClass) || Boolean.class.getName().equals(propClass) || Integer.class
246                .getName().equals(propClass) || JavaUtils.isPrimitive(propClass));
247    }
248
249    private static Object parseSimpleValue(XMLStreamReader reader, String propClass) throws XMLStreamException {
250        if (String.class.getName().equals(propClass)) {
251            return StAXUtils.elementAsString(reader);
252        } else if (Boolean.class.getName().equals(propClass)) {
253            return StAXUtils.elementAsBoolean(reader);
254        } else if (Integer.class.getName().equals(propClass)) {
255            return StAXUtils.elementAsInt(reader);
256        } else if (boolean.class.getName().equals(propClass)) {
257            return StAXUtils.elementAsBoolean(reader);
258        } else {
259            throw MESSAGES.unsupportedPropertyClass(propClass);
260        }
261    }
262
263    @SuppressWarnings({ "rawtypes", "unchecked" })
264    private static List parseListProperty(XMLStreamReader reader, String propClass, String elementClass)
265            throws XMLStreamException {
266        List list = null;
267        try {
268            list = (List) Class.forName(propClass).newInstance();
269        } catch (Exception e) {
270            throw MESSAGES.cannotInstantiateList(e, propClass);
271        }
272        while (reader.hasNext()) {
273            switch (reader.nextTag()) {
274                case XMLStreamConstants.END_ELEMENT: {
275                    if (match(reader, NS, LIST)) {
276                        return list;
277                    } else {
278                        throw MESSAGES.unexpectedEndTag(reader.getLocalName());
279                    }
280                }
281                case XMLStreamConstants.START_ELEMENT: {
282                    if (match(reader, NS, VALUE)) {
283                        list.add(parseSimpleValue(reader, elementClass));
284                    } else {
285                        throw MESSAGES.unexpectedElement(reader.getLocalName());
286                    }
287                }
288            }
289        }
290        throw MESSAGES.unexpectedEndOfDocument();
291    }
292
293    @SuppressWarnings("rawtypes")
294    private static Map parseMapProperty(XMLStreamReader reader, String propClass, String keyClass, String valueClass, ClassLoader loader)
295            throws XMLStreamException {
296        Map map = null;
297        try {
298            map = (Map) Class.forName(propClass, true, loader).newInstance();
299        } catch (Exception e) {
300            throw MESSAGES.cannotInstantiateMap(e, propClass);
301        }
302        while (reader.hasNext()) {
303            switch (reader.nextTag()) {
304                case XMLStreamConstants.END_ELEMENT: {
305                    if (match(reader, NS, MAP)) {
306                        return map;
307                    } else {
308                        throw MESSAGES.unexpectedEndTag(reader.getLocalName());
309                    }
310                }
311                case XMLStreamConstants.START_ELEMENT: {
312                    if (match(reader, NS, ENTRY)) {
313                        parseMapEntry(reader, map, keyClass, valueClass);
314                    } else {
315                        throw MESSAGES.unexpectedElement(reader.getLocalName());
316                    }
317                }
318            }
319        }
320        throw MESSAGES.unexpectedEndOfDocument();
321    }
322
323    @SuppressWarnings({ "rawtypes", "unchecked" })
324    private static void parseMapEntry(XMLStreamReader reader, Map map, String keyClass, String valueClass)
325            throws XMLStreamException {
326        boolean keyStartDone = false, valueStartDone = false;
327        Object key = null;
328        Object value = null;
329        while (reader.hasNext()) {
330            switch (reader.nextTag()) {
331                case XMLStreamConstants.END_ELEMENT: {
332                    if (match(reader, NS, ENTRY) && keyStartDone && valueStartDone) {
333                        map.put(key, value);
334                        return;
335                    } else {
336                        throw MESSAGES.unexpectedEndTag(reader.getLocalName());
337                    }
338                }
339                case XMLStreamConstants.START_ELEMENT: {
340                    if (match(reader, NS, KEY)) {
341                        keyStartDone = true;
342                        key = parseSimpleValue(reader, keyClass);
343                    } else if (match(reader, NS, VALUE)) {
344                        valueStartDone = true;
345                        value = parseSimpleValue(reader, valueClass);
346                    } else {
347                        throw MESSAGES.unexpectedElement(reader.getLocalName());
348                    }
349                }
350            }
351        }
352        throw MESSAGES.unexpectedEndOfDocument();
353    }
354
355    /**
356     * Get context classloader.
357     *
358     * @return the current context classloader
359     */
360    private static ClassLoader getContextClassLoader() {
361        SecurityManager sm = System.getSecurityManager();
362        if (sm == null) {
363            return Thread.currentThread().getContextClassLoader();
364        } else {
365            return AccessController.doPrivileged(new PrivilegedAction<ClassLoader>() {
366                public ClassLoader run() {
367                    return Thread.currentThread().getContextClassLoader();
368                }
369            });
370        }
371    }
372
373    /**
374     * Set context classloader.
375     *
376     * @param classLoader the classloader
377     */
378    private static void setContextClassLoader(final ClassLoader classLoader) {
379        if (System.getSecurityManager() == null) {
380            Thread.currentThread().setContextClassLoader(classLoader);
381        } else {
382            AccessController.doPrivileged(new PrivilegedAction<Object>() {
383                public Object run() {
384                    Thread.currentThread().setContextClassLoader(classLoader);
385                    return null;
386                }
387            });
388        }
389    }
390}