src/share/jaxws_classes/com/sun/xml/internal/ws/api/PropertySet.java

Print this page

        

*** 1,7 **** /* ! * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. Oracle designates this --- 1,7 ---- /* ! * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. Oracle designates this
*** 23,282 **** * questions. */ package com.sun.xml.internal.ws.api; - import com.sun.istack.internal.NotNull; - import com.sun.istack.internal.Nullable; - import com.sun.xml.internal.ws.util.ReadOnlyPropertyException; - - import java.lang.reflect.Field; - import java.lang.reflect.InvocationTargetException; - import java.lang.reflect.Method; - import java.security.AccessController; - import java.security.PrivilegedAction; - import java.util.AbstractMap; - import java.util.HashMap; - import java.util.HashSet; import java.util.Map; - import java.util.Map.Entry; import java.util.Set; /** ! * A set of "properties" that can be accessed via strongly-typed fields ! * as well as reflexibly through the property name. * ! * @author Kohsuke Kawaguchi ! */ ! @SuppressWarnings("SuspiciousMethodCalls") ! public abstract class PropertySet implements com.sun.xml.internal.org.jvnet.ws.message.PropertySet { ! ! /** ! * Creates a new instance of TypedMap. */ ! protected PropertySet() {} ! /** ! * Represents the list of strongly-typed known propertyies * (keyed by property names.) * * <p> * Just giving it an alias to make the use of this class more fool-proof. */ ! protected static final class PropertyMap extends HashMap<String,Accessor> {} ! ! /** ! * Map representing the Fields and Methods annotated with {@link Property}. ! * Model of {@link PropertySet} class. ! * ! * <p> ! * At the end of the derivation chain this method just needs to be implemented ! * as: ! * ! * <pre> ! * private static final PropertyMap model; ! * static { ! * model = parse(MyDerivedClass.class); ! * } ! * protected PropertyMap getPropertyMap() { ! * return model; ! * } ! * </pre> ! */ ! protected abstract PropertyMap getPropertyMap(); ! ! // maybe we can use this some time ! ///** ! // * If all the properties defined on this {@link PropertySet} has a certain prefix ! // * (such as, say, "javax.xml.ws.http."), then return it. ! // * ! // * <p> ! // * Returning a non-null name from this method allows methods like ! // * {@link #get(Object)} and {@link #put(String, Object)} to work faster. ! // * This is especially so with {@link DistributedPropertySet}, so implementations ! // * are encouraged to set a common prefix, as much as possible. ! // * ! // * <p> ! // * Currently, this is used only by {@link DistributedPropertySet}. ! // * ! // * @return ! // * Null if no such common prefix exists. Otherwise string like ! // * "javax.xml.ws.http." (the dot at the last is usually preferrable, ! // * so that properties like "javax.xml.ws.https.something" won't match. ! // */ ! //protected abstract String getPropertyPrefix(); /** ! * This method parses a class for fields and methods with {@link Property}. */ protected static PropertyMap parse(final Class clazz) { ! // make all relevant fields and methods accessible. ! // this allows runtime to skip the security check, so they runs faster. ! return AccessController.doPrivileged(new PrivilegedAction<PropertyMap>() { ! public PropertyMap run() { ! PropertyMap props = new PropertyMap(); ! for( Class c=clazz; c!=null; c=c.getSuperclass()) { ! for (Field f : c.getDeclaredFields()) { ! Property cp = f.getAnnotation(Property.class); ! if(cp!=null) { ! for(String value : cp.value()) { ! props.put(value, new FieldAccessor(f, value)); ! } ! } ! } ! for (Method m : c.getDeclaredMethods()) { ! Property cp = m.getAnnotation(Property.class); ! if(cp!=null) { ! String name = m.getName(); ! assert name.startsWith("get") || name.startsWith("is"); ! ! String setName = name.startsWith("is") ? "set"+name.substring(3) : // isFoo -> setFoo ! 's'+name.substring(1); // getFoo -> setFoo ! Method setter; ! try { ! setter = clazz.getMethod(setName,m.getReturnType()); ! } catch (NoSuchMethodException e) { ! setter = null; // no setter ! } ! for(String value : cp.value()) { ! props.put(value, new MethodAccessor(m, setter, value)); ! } ! } ! } ! } ! ! return props; ! } ! }); ! } ! ! /** ! * Represents a typed property defined on a {@link PropertySet}. ! */ ! protected interface Accessor { ! String getName(); ! boolean hasValue(PropertySet props); ! Object get(PropertySet props); ! void set(PropertySet props, Object value); ! } ! ! static final class FieldAccessor implements Accessor { ! /** ! * Field with the annotation. ! */ ! private final Field f; ! ! /** ! * One of the values in {@link Property} annotation on {@link #f}. ! */ ! private final String name; ! ! protected FieldAccessor(Field f, String name) { ! this.f = f; ! f.setAccessible(true); ! this.name = name; ! } ! ! public String getName() { ! return name; ! } ! ! public boolean hasValue(PropertySet props) { ! return get(props)!=null; ! } ! ! public Object get(PropertySet props) { ! try { ! return f.get(props); ! } catch (IllegalAccessException e) { ! throw new AssertionError(); ! } ! } ! ! public void set(PropertySet props, Object value) { ! try { ! f.set(props,value); ! } catch (IllegalAccessException e) { ! throw new AssertionError(); ! } ! } ! } ! ! static final class MethodAccessor implements Accessor { ! /** ! * Getter method. ! */ ! private final @NotNull Method getter; ! /** ! * Setter method. ! * Some property is read-only. ! */ ! private final @Nullable Method setter; ! ! /** ! * One of the values in {@link Property} annotation on {@link #getter}. ! */ ! private final String name; ! ! protected MethodAccessor(Method getter, Method setter, String value) { ! this.getter = getter; ! this.setter = setter; ! this.name = value; ! getter.setAccessible(true); ! if(setter!=null) ! setter.setAccessible(true); ! } ! ! public String getName() { ! return name; ! } ! ! public boolean hasValue(PropertySet props) { ! return get(props)!=null; ! } ! ! public Object get(PropertySet props) { ! try { ! return getter.invoke(props); ! } catch (IllegalAccessException e) { ! throw new AssertionError(); ! } catch (InvocationTargetException e) { ! handle(e); ! return 0; // never reach here ! } ! } ! ! public void set(PropertySet props, Object value) { ! if(setter==null) ! throw new ReadOnlyPropertyException(getName()); ! try { ! setter.invoke(props,value); ! } catch (IllegalAccessException e) { ! throw new AssertionError(); ! } catch (InvocationTargetException e) { ! handle(e); ! } ! } ! ! /** ! * Since we don't expect the getter/setter to throw a checked exception, ! * it should be possible to make the exception propagation transparent. ! * That's what we are trying to do here. ! */ ! private Exception handle(InvocationTargetException e) { ! Throwable t = e.getTargetException(); ! if(t instanceof Error) ! throw (Error)t; ! if(t instanceof RuntimeException) ! throw (RuntimeException)t; ! throw new Error(e); ! } ! } ! ! ! public final boolean containsKey(Object key) { ! return get(key)!=null; } /** * Gets the name of the property. * --- 23,61 ---- * questions. */ package com.sun.xml.internal.ws.api; import java.util.Map; import java.util.Set; + import java.util.Map.Entry; /** ! * Placeholder for backwards compatibility. * ! * @deprecated Use com.oracle.webservices.internal.api.message.PropertySet instead. ! * @author snajper */ ! public abstract class PropertySet extends com.oracle.webservices.internal.api.message.BasePropertySet { /** ! * Represents the list of strongly-typed known properties * (keyed by property names.) * * <p> * Just giving it an alias to make the use of this class more fool-proof. + * @deprecated */ ! protected static class PropertyMap extends com.oracle.webservices.internal.api.message.BasePropertySet.PropertyMap {} /** ! * @deprecated */ protected static PropertyMap parse(final Class clazz) { ! com.oracle.webservices.internal.api.message.BasePropertySet.PropertyMap pm = com.oracle.webservices.internal.api.message.BasePropertySet.parse(clazz); ! PropertyMap map = new PropertyMap(); ! map.putAll(pm); ! return map; } /** * Gets the name of the property. *
*** 314,326 **** } else { throw new IllegalArgumentException("Undefined property "+key); } } - /** - * Checks if this {@link PropertySet} supports a property of the given name. - */ public boolean supports(Object key) { return getPropertyMap().containsKey(key); } public Object remove(Object key) { --- 93,102 ----
*** 332,374 **** } else { throw new IllegalArgumentException("Undefined property "+key); } } ! ! /** ! * Lazily created view of {@link Property}s that ! * forms the core of {@link #createMapView()}. ! */ ! /*package*/ Set<Entry<String,Object>> mapViewCore; ! ! /** ! * Creates a {@link Map} view of this {@link PropertySet}. ! * ! * <p> ! * This map is partially live, in the sense that values you set to it ! * will be reflected to {@link PropertySet}. ! * ! * <p> ! * However, this map may not pick up changes made ! * to {@link PropertySet} after the view is created. ! * ! * @return ! * always non-null valid instance. ! */ ! public final Map<String,Object> createMapView() { ! final Set<Entry<String,Object>> core = new HashSet<Entry<String,Object>>(); ! createEntrySet(core); ! ! return new AbstractMap<String, Object>() { ! public Set<Entry<String,Object>> entrySet() { ! return core; ! } ! }; ! } ! ! /*package*/ void createEntrySet(Set<Entry<String,Object>> core) { for (final Entry<String, Accessor> e : getPropertyMap().entrySet()) { core.add(new Entry<String, Object>() { public String getKey() { return e.getKey(); } --- 108,118 ---- } else { throw new IllegalArgumentException("Undefined property "+key); } } ! protected void createEntrySet(Set<Entry<String,Object>> core) { for (final Entry<String, Accessor> e : getPropertyMap().entrySet()) { core.add(new Entry<String, Object>() { public String getKey() { return e.getKey(); }
*** 384,389 **** --- 128,135 ---- return old; } }); } } + + protected abstract PropertyMap getPropertyMap(); }