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();
}