http://git-wip-us.apache.org/repos/asf/struts/blob/31af5842/xwork-core/src/main/java/com/opensymphony/xwork2/inject/Scope.java ---------------------------------------------------------------------- diff --git a/xwork-core/src/main/java/com/opensymphony/xwork2/inject/Scope.java b/xwork-core/src/main/java/com/opensymphony/xwork2/inject/Scope.java deleted file mode 100644 index 62443f7..0000000 --- a/xwork-core/src/main/java/com/opensymphony/xwork2/inject/Scope.java +++ /dev/null @@ -1,214 +0,0 @@ -/** - * Copyright (C) 2006 Google Inc. - * <p/> - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * <p/> - * http://www.apache.org/licenses/LICENSE-2.0 - * <p/> - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.opensymphony.xwork2.inject; - -import java.util.concurrent.Callable; - -/** - * Scope of an injected objects. - * - * @author crazybob - */ -public enum Scope { - - /** - * One instance per injection. - */ - DEFAULT { - @Override - <T> InternalFactory<? extends T> scopeFactory(Class<T> type, String name, - InternalFactory<? extends T> factory) { - return factory; - } - }, - - /** - * One instance per container. - */ - SINGLETON { - @Override - <T> InternalFactory<? extends T> scopeFactory(Class<T> type, String name, final InternalFactory<? extends T> factory) { - return new InternalFactory<T>() { - T instance; - - public T create(InternalContext context) { - synchronized (context.getContainer()) { - if (instance == null) { - instance = factory.create(context); - } - return instance; - } - } - - @Override - public String toString() { - return factory.toString(); - } - }; - } - }, - - /** - * One instance per thread. - * <p/> - * <p><b>Note:</b> if a thread local object strongly references its {@link - * Container}, neither the {@code Container} nor the object will be - * eligible for garbage collection, i.e. memory leak. - */ - THREAD { - @Override - <T> InternalFactory<? extends T> scopeFactory(Class<T> type, String name, final InternalFactory<? extends T> factory) { - return new InternalFactory<T>() { - final ThreadLocal<T> threadLocal = new ThreadLocal<T>(); - - public T create(final InternalContext context) { - T t = threadLocal.get(); - if (t == null) { - t = factory.create(context); - threadLocal.set(t); - } - return t; - } - - @Override - public String toString() { - return factory.toString(); - } - }; - } - }, - - /** - * One instance per request. - */ - REQUEST { - @Override - <T> InternalFactory<? extends T> scopeFactory(final Class<T> type, final String name, final InternalFactory<? extends T> factory) { - return new InternalFactory<T>() { - public T create(InternalContext context) { - Strategy strategy = context.getScopeStrategy(); - try { - return strategy.findInRequest( - type, name, toCallable(context, factory)); - } catch (Exception e) { - throw new RuntimeException(e); - } - } - - @Override - public String toString() { - return factory.toString(); - } - }; - } - }, - - /** - * One instance per session. - */ - SESSION { - @Override - <T> InternalFactory<? extends T> scopeFactory(final Class<T> type, final String name, final InternalFactory<? extends T> factory) { - return new InternalFactory<T>() { - public T create(InternalContext context) { - Strategy strategy = context.getScopeStrategy(); - try { - return strategy.findInSession( - type, name, toCallable(context, factory)); - } catch (Exception e) { - throw new RuntimeException(e); - } - } - - @Override - public String toString() { - return factory.toString(); - } - }; - } - }, - - /** - * One instance per wizard. - */ - WIZARD { - @Override - <T> InternalFactory<? extends T> scopeFactory(final Class<T> type, final String name, final InternalFactory<? extends T> factory) { - return new InternalFactory<T>() { - public T create(InternalContext context) { - Strategy strategy = context.getScopeStrategy(); - try { - return strategy.findInWizard( - type, name, toCallable(context, factory)); - } catch (Exception e) { - throw new RuntimeException(e); - } - } - - @Override - public String toString() { - return factory.toString(); - } - }; - } - }; - - <T> Callable<? extends T> toCallable(final InternalContext context, - final InternalFactory<? extends T> factory) { - return new Callable<T>() { - public T call() throws Exception { - return factory.create(context); - } - }; - } - - /** - * Wraps factory with scoping logic. - */ - abstract <T> InternalFactory<? extends T> scopeFactory( - Class<T> type, String name, InternalFactory<? extends T> factory); - - /** - * Pluggable scoping strategy. Enables users to provide custom - * implementations of request, session, and wizard scopes. Implement and - * pass to {@link - * Container#setScopeStrategy(com.opensymphony.xwork2.inject.Scope.Strategy)}. - */ - public interface Strategy { - - /** - * Finds an object for the given type and name in the request scope. - * Creates a new object if necessary using the given factory. - */ - <T> T findInRequest(Class<T> type, String name, - Callable<? extends T> factory) throws Exception; - - /** - * Finds an object for the given type and name in the session scope. - * Creates a new object if necessary using the given factory. - */ - <T> T findInSession(Class<T> type, String name, - Callable<? extends T> factory) throws Exception; - - /** - * Finds an object for the given type and name in the wizard scope. - * Creates a new object if necessary using the given factory. - */ - <T> T findInWizard(Class<T> type, String name, - Callable<? extends T> factory) throws Exception; - } -}
http://git-wip-us.apache.org/repos/asf/struts/blob/31af5842/xwork-core/src/main/java/com/opensymphony/xwork2/inject/Scoped.java ---------------------------------------------------------------------- diff --git a/xwork-core/src/main/java/com/opensymphony/xwork2/inject/Scoped.java b/xwork-core/src/main/java/com/opensymphony/xwork2/inject/Scoped.java deleted file mode 100644 index 31a9447..0000000 --- a/xwork-core/src/main/java/com/opensymphony/xwork2/inject/Scoped.java +++ /dev/null @@ -1,37 +0,0 @@ -/** - * Copyright (C) 2006 Google Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.opensymphony.xwork2.inject; - -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import static java.lang.annotation.RetentionPolicy.RUNTIME; -import java.lang.annotation.Target; - -/** - * Annotates a scoped implementation class. - * - * @author crazybob - */ -@Target(ElementType.TYPE) -@Retention(RUNTIME) -public @interface Scoped { - - /** - * Scope. - */ - Scope value(); -} http://git-wip-us.apache.org/repos/asf/struts/blob/31af5842/xwork-core/src/main/java/com/opensymphony/xwork2/inject/package-info.java ---------------------------------------------------------------------- diff --git a/xwork-core/src/main/java/com/opensymphony/xwork2/inject/package-info.java b/xwork-core/src/main/java/com/opensymphony/xwork2/inject/package-info.java deleted file mode 100644 index 6e26e24..0000000 --- a/xwork-core/src/main/java/com/opensymphony/xwork2/inject/package-info.java +++ /dev/null @@ -1,30 +0,0 @@ -/** - * Copyright (C) 2006 Google Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * <i>Guice</i> (pronounced "juice"). A lightweight dependency injection - * container. Features include: - * - * <ul> - * <li>constructor, method, and field injection</li> - * <li>static method and field injection</li> - * <li>circular reference support (including constructors if you depend upon - * interfaces)</li> - * <li>high performance</li> - * <li>externalize what needs to be and no more</li> - * </ul> - */ -package com.opensymphony.xwork2.inject; http://git-wip-us.apache.org/repos/asf/struts/blob/31af5842/xwork-core/src/main/java/com/opensymphony/xwork2/inject/util/FinalizablePhantomReference.java ---------------------------------------------------------------------- diff --git a/xwork-core/src/main/java/com/opensymphony/xwork2/inject/util/FinalizablePhantomReference.java b/xwork-core/src/main/java/com/opensymphony/xwork2/inject/util/FinalizablePhantomReference.java deleted file mode 100644 index 869b96b..0000000 --- a/xwork-core/src/main/java/com/opensymphony/xwork2/inject/util/FinalizablePhantomReference.java +++ /dev/null @@ -1,35 +0,0 @@ -/** - * Copyright (C) 2006 Google Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.opensymphony.xwork2.inject.util; - -import java.lang.ref.PhantomReference; - -/** - * Phantom reference with a {@link com.opensymphony.xwork2.inject.util.FinalizableReference#finalizeReferent() finalizeReferent()} method which a - * background thread invokes after the garbage collector reclaims the - * referent. This is a simpler alternative to using a {@link - * java.lang.ref.ReferenceQueue}. - * - * @author [email protected] (Bob Lee) - */ -public abstract class FinalizablePhantomReference<T> - extends PhantomReference<T> implements FinalizableReference { - - protected FinalizablePhantomReference(T referent) { - super(referent, FinalizableReferenceQueue.getInstance()); - } -} http://git-wip-us.apache.org/repos/asf/struts/blob/31af5842/xwork-core/src/main/java/com/opensymphony/xwork2/inject/util/FinalizableReference.java ---------------------------------------------------------------------- diff --git a/xwork-core/src/main/java/com/opensymphony/xwork2/inject/util/FinalizableReference.java b/xwork-core/src/main/java/com/opensymphony/xwork2/inject/util/FinalizableReference.java deleted file mode 100644 index 16653e2..0000000 --- a/xwork-core/src/main/java/com/opensymphony/xwork2/inject/util/FinalizableReference.java +++ /dev/null @@ -1,32 +0,0 @@ -/** - * Copyright (C) 2006 Google Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.opensymphony.xwork2.inject.util; - -/** - * Package-private interface implemented by references that have code to run - * after garbage collection of their referents. - * - * @author [email protected] (Bob Lee) - */ -interface FinalizableReference { - - /** - * Invoked on a background thread after the referent has been garbage - * collected. - */ - void finalizeReferent(); -} http://git-wip-us.apache.org/repos/asf/struts/blob/31af5842/xwork-core/src/main/java/com/opensymphony/xwork2/inject/util/FinalizableReferenceQueue.java ---------------------------------------------------------------------- diff --git a/xwork-core/src/main/java/com/opensymphony/xwork2/inject/util/FinalizableReferenceQueue.java b/xwork-core/src/main/java/com/opensymphony/xwork2/inject/util/FinalizableReferenceQueue.java deleted file mode 100644 index 72121ef..0000000 --- a/xwork-core/src/main/java/com/opensymphony/xwork2/inject/util/FinalizableReferenceQueue.java +++ /dev/null @@ -1,77 +0,0 @@ -/** - * Copyright (C) 2006 Google Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.opensymphony.xwork2.inject.util; - -import java.lang.ref.Reference; -import java.lang.ref.ReferenceQueue; -import java.util.logging.Level; -import java.util.logging.Logger; - -/** - * Starts a background thread that cleans up after reclaimed referents. - * - * @author Bob Lee ([email protected]) - */ -class FinalizableReferenceQueue extends ReferenceQueue<Object> { - - private static final Logger logger = - Logger.getLogger(FinalizableReferenceQueue.class.getName()); - - private FinalizableReferenceQueue() {} - - void cleanUp(Reference reference) { - try { - ((FinalizableReference) reference).finalizeReferent(); - } catch (Throwable t) { - deliverBadNews(t); - } - } - - void deliverBadNews(Throwable t) { - logger.log(Level.SEVERE, "Error cleaning up after reference.", t); - } - - void start() { - Thread thread = new Thread("FinalizableReferenceQueue") { - @Override - public void run() { - while (true) { - try { - cleanUp(remove()); - } catch (InterruptedException e) { /* ignore */ } - } - } - }; - thread.setDaemon(true); - thread.start(); - } - - static ReferenceQueue<Object> instance = createAndStart(); - - static FinalizableReferenceQueue createAndStart() { - FinalizableReferenceQueue queue = new FinalizableReferenceQueue(); - queue.start(); - return queue; - } - - /** - * Gets instance. - */ - public static ReferenceQueue<Object> getInstance() { - return instance; - } -} http://git-wip-us.apache.org/repos/asf/struts/blob/31af5842/xwork-core/src/main/java/com/opensymphony/xwork2/inject/util/FinalizableSoftReference.java ---------------------------------------------------------------------- diff --git a/xwork-core/src/main/java/com/opensymphony/xwork2/inject/util/FinalizableSoftReference.java b/xwork-core/src/main/java/com/opensymphony/xwork2/inject/util/FinalizableSoftReference.java deleted file mode 100644 index eeb1c20..0000000 --- a/xwork-core/src/main/java/com/opensymphony/xwork2/inject/util/FinalizableSoftReference.java +++ /dev/null @@ -1,34 +0,0 @@ -/** - * Copyright (C) 2006 Google Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.opensymphony.xwork2.inject.util; - -import java.lang.ref.SoftReference; - -/** - * Soft reference with a {@link com.opensymphony.xwork2.inject.util.FinalizableReference#finalizeReferent() finalizeReferent()} method which a background - * thread invokes after the garbage collector reclaims the referent. This is a - * simpler alternative to using a {@link java.lang.ref.ReferenceQueue}. - * - * @author [email protected] (Bob Lee) - */ -public abstract class FinalizableSoftReference<T> extends SoftReference<T> - implements FinalizableReference { - - protected FinalizableSoftReference(T referent) { - super(referent, FinalizableReferenceQueue.getInstance()); - } -} http://git-wip-us.apache.org/repos/asf/struts/blob/31af5842/xwork-core/src/main/java/com/opensymphony/xwork2/inject/util/FinalizableWeakReference.java ---------------------------------------------------------------------- diff --git a/xwork-core/src/main/java/com/opensymphony/xwork2/inject/util/FinalizableWeakReference.java b/xwork-core/src/main/java/com/opensymphony/xwork2/inject/util/FinalizableWeakReference.java deleted file mode 100644 index 7c3a67f..0000000 --- a/xwork-core/src/main/java/com/opensymphony/xwork2/inject/util/FinalizableWeakReference.java +++ /dev/null @@ -1,34 +0,0 @@ -/** - * Copyright (C) 2006 Google Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.opensymphony.xwork2.inject.util; - -import java.lang.ref.WeakReference; - -/** - * Weak reference with a {@link com.opensymphony.xwork2.inject.util.FinalizableReference#finalizeReferent() finalizeReferent()} method which a background - * thread invokes after the garbage collector reclaims the referent. This is a - * simpler alternative to using a {@link java.lang.ref.ReferenceQueue}. - * - * @author [email protected] (Bob Lee) - */ -public abstract class FinalizableWeakReference<T> extends WeakReference<T> - implements FinalizableReference { - - protected FinalizableWeakReference(T referent) { - super(referent, FinalizableReferenceQueue.getInstance()); - } -} http://git-wip-us.apache.org/repos/asf/struts/blob/31af5842/xwork-core/src/main/java/com/opensymphony/xwork2/inject/util/Function.java ---------------------------------------------------------------------- diff --git a/xwork-core/src/main/java/com/opensymphony/xwork2/inject/util/Function.java b/xwork-core/src/main/java/com/opensymphony/xwork2/inject/util/Function.java deleted file mode 100644 index fd21237..0000000 --- a/xwork-core/src/main/java/com/opensymphony/xwork2/inject/util/Function.java +++ /dev/null @@ -1,44 +0,0 @@ -/** - * Copyright (C) 2006 Google Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.opensymphony.xwork2.inject.util; - -/** - * A Function provides a transformation on an object and returns the resulting - * object. For example, a {@code StringToIntegerFunction} may implement - * <code>Function<String,Integer></code> and transform integers in String - * format to Integer format. - * - * <p>The transformation on the source object does not necessarily result in - * an object of a different type. For example, a - * {@code FarenheitToCelciusFunction} may implement - * <code>Function<Float,Float></code>. - * - * <p>Implementors of Function which may cause side effects upon evaluation are - * strongly encouraged to state this fact clearly in their API documentation. - */ -public interface Function<F,T> { - - /** - * Applies the function to an object of type {@code F}, resulting in an object - * of type {@code T}. Note that types {@code F} and {@code T} may or may not - * be the same. - * - * @param from The source object. - * @return The resulting object. - */ - T apply(F from); -} http://git-wip-us.apache.org/repos/asf/struts/blob/31af5842/xwork-core/src/main/java/com/opensymphony/xwork2/inject/util/ReferenceCache.java ---------------------------------------------------------------------- diff --git a/xwork-core/src/main/java/com/opensymphony/xwork2/inject/util/ReferenceCache.java b/xwork-core/src/main/java/com/opensymphony/xwork2/inject/util/ReferenceCache.java deleted file mode 100644 index 9ebf545..0000000 --- a/xwork-core/src/main/java/com/opensymphony/xwork2/inject/util/ReferenceCache.java +++ /dev/null @@ -1,177 +0,0 @@ -/** - * Copyright (C) 2006 Google Inc. - * <p/> - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * <p/> - * http://www.apache.org/licenses/LICENSE-2.0 - * <p/> - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.opensymphony.xwork2.inject.util; - -import java.io.IOException; -import java.io.ObjectInputStream; -import java.util.concurrent.*; - -import static com.opensymphony.xwork2.inject.util.ReferenceType.STRONG; - -/** - * Extends {@link ReferenceMap} to support lazy loading values by overriding - * {@link #create(Object)}. - * - * @author [email protected] (Bob Lee) - */ -public abstract class ReferenceCache<K, V> extends ReferenceMap<K, V> { - - private static final long serialVersionUID = 0; - - transient ConcurrentMap<Object, Future<V>> futures = new ConcurrentHashMap<>(); - transient ThreadLocal<Future<V>> localFuture = new ThreadLocal<>(); - - public ReferenceCache(ReferenceType keyReferenceType, ReferenceType valueReferenceType) { - super(keyReferenceType, valueReferenceType); - } - - /** - * Equivalent to {@code new ReferenceCache(STRONG, STRONG)}. - */ - public ReferenceCache() { - super(STRONG, STRONG); - } - - /** - * Override to lazy load values. Use as an alternative to {@link - * #put(Object, Object)}. Invoked by getter if value isn't already cached. - * Must not return {@code null}. This method will not be called again until - * the garbage collector reclaims the returned value. - */ - protected abstract V create(K key); - - V internalCreate(K key) { - try { - FutureTask<V> futureTask = new FutureTask<>(new CallableCreate(key)); - - // use a reference so we get the same equality semantics. - Object keyReference = referenceKey(key); - Future<V> future = futures.putIfAbsent(keyReference, futureTask); - if (future == null) { - // winning thread. - try { - if (localFuture.get() != null) { - throw new IllegalStateException("Nested creations within the same cache are not allowed."); - } - localFuture.set(futureTask); - futureTask.run(); - V value = futureTask.get(); - putStrategy().execute(this, keyReference, referenceValue(keyReference, value)); - return value; - } finally { - localFuture.remove(); - futures.remove(keyReference); - } - } else { - // wait for winning thread. - return future.get(); - } - } catch (InterruptedException e) { - throw new RuntimeException(e); - } catch (ExecutionException e) { - Throwable cause = e.getCause(); - if (cause instanceof RuntimeException) { - throw (RuntimeException) cause; - } else if (cause instanceof Error) { - throw (Error) cause; - } - throw new RuntimeException(cause); - } - } - - /** - * {@inheritDoc} - * <p/> - * If this map does not contain an entry for the given key and {@link - * #create(Object)} has been overridden, this method will create a new - * value, put it in the map, and return it. - * - * @throws NullPointerException if {@link #create(Object)} returns null. - * @throws java.util.concurrent.CancellationException if the creation is - * cancelled. See {@link #cancel()}. - */ - @SuppressWarnings("unchecked") - @Override - public V get(final Object key) { - V value = super.get(key); - return (value == null) ? internalCreate((K) key) : value; - } - - /** - * Cancels the current {@link #create(Object)}. Throws {@link - * java.util.concurrent.CancellationException} to all clients currently - * blocked on {@link #get(Object)}. - */ - protected void cancel() { - Future<V> future = localFuture.get(); - if (future == null) { - throw new IllegalStateException("Not in create()."); - } - future.cancel(false); - } - - class CallableCreate implements Callable<V> { - - K key; - - public CallableCreate(K key) { - this.key = key; - } - - public V call() { - // try one more time (a previous future could have come and gone.) - V value = internalGet(key); - if (value != null) { - return value; - } - - // create value. - value = create(key); - if (value == null) { - throw new NullPointerException("create(K) returned null for: " + key); - } - return value; - } - } - - /** - * Returns a {@code ReferenceCache} delegating to the specified {@code - * function}. The specified function must not return {@code null}. - */ - public static <K, V> ReferenceCache<K, V> of( - ReferenceType keyReferenceType, - ReferenceType valueReferenceType, - final Function<? super K, ? extends V> function) { - ensureNotNull(function); - return new ReferenceCache<K, V>(keyReferenceType, valueReferenceType) { - @Override - protected V create(K key) { - return function.apply(key); - } - - private static final long serialVersionUID = 0; - }; - } - - private void readObject(ObjectInputStream in) throws IOException, - ClassNotFoundException { - in.defaultReadObject(); - this.futures = new ConcurrentHashMap<>(); - this.localFuture = new ThreadLocal<>(); - } - -} http://git-wip-us.apache.org/repos/asf/struts/blob/31af5842/xwork-core/src/main/java/com/opensymphony/xwork2/inject/util/ReferenceMap.java ---------------------------------------------------------------------- diff --git a/xwork-core/src/main/java/com/opensymphony/xwork2/inject/util/ReferenceMap.java b/xwork-core/src/main/java/com/opensymphony/xwork2/inject/util/ReferenceMap.java deleted file mode 100644 index 4d8eebb..0000000 --- a/xwork-core/src/main/java/com/opensymphony/xwork2/inject/util/ReferenceMap.java +++ /dev/null @@ -1,605 +0,0 @@ -/** - * Copyright (C) 2006 Google Inc. - * <p/> - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * <p/> - * http://www.apache.org/licenses/LICENSE-2.0 - * <p/> - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.opensymphony.xwork2.inject.util; - -import java.io.IOException; -import java.io.ObjectInputStream; -import java.io.ObjectOutputStream; -import java.io.Serializable; -import java.lang.ref.Reference; -import java.util.*; -import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.ConcurrentMap; - -import static com.opensymphony.xwork2.inject.util.ReferenceType.STRONG; - -/** - * Concurrent hash map that wraps keys and/or values in soft or weak - * references. Does not support null keys or values. Uses identity equality - * for weak and soft keys. - * - * <p>The concurrent semantics of {@link ConcurrentHashMap} combined with the - * fact that the garbage collector can asynchronously reclaim and clean up - * after keys and values at any time can lead to some racy semantics. For - * example, {@link #size()} returns an upper bound on the size, i.e. the actual - * size may be smaller in cases where the key or value has been reclaimed but - * the map entry has not been cleaned up yet. - * - * <p>Another example: If {@link #get(Object)} cannot find an existing entry - * for a key, it will try to create one. This operation is not atomic. One - * thread could {@link #put(Object, Object)} a value between the time another - * thread running {@code get()} checks for an entry and decides to create one. - * In this case, the newly created value will replace the put value in the - * map. Also, two threads running {@code get()} concurrently can potentially - * create duplicate values for a given key. - * - * <p>In other words, this class is great for caching but not atomicity. - * - * @author [email protected] (Bob Lee) - */ -@SuppressWarnings("unchecked") -public class ReferenceMap<K, V> implements Map<K, V>, Serializable { - - private static final long serialVersionUID = 0; - - transient ConcurrentMap<Object, Object> delegate; - - final ReferenceType keyReferenceType; - final ReferenceType valueReferenceType; - - /** - * Concurrent hash map that wraps keys and/or values based on specified - * reference types. - * - * @param keyReferenceType key reference type - * @param valueReferenceType value reference type - */ - public ReferenceMap(ReferenceType keyReferenceType, - ReferenceType valueReferenceType) { - ensureNotNull(keyReferenceType, valueReferenceType); - - if (keyReferenceType == ReferenceType.PHANTOM || valueReferenceType == ReferenceType.PHANTOM) { - throw new IllegalArgumentException("Phantom references not supported."); - } - - this.delegate = new ConcurrentHashMap<>(); - this.keyReferenceType = keyReferenceType; - this.valueReferenceType = valueReferenceType; - } - - V internalGet(K key) { - Object valueReference = delegate.get(makeKeyReferenceAware(key)); - return valueReference == null ? null : (V) dereferenceValue(valueReference); - } - - public V get(final Object key) { - ensureNotNull(key); - return internalGet((K) key); - } - - V execute(Strategy strategy, K key, V value) { - ensureNotNull(key, value); - Object keyReference = referenceKey(key); - Object valueReference = strategy.execute(this, keyReference, referenceValue(keyReference, value)); - return valueReference == null ? null : (V) dereferenceValue(valueReference); - } - - public V put(K key, V value) { - return execute(putStrategy(), key, value); - } - - public V remove(Object key) { - ensureNotNull(key); - Object referenceAwareKey = makeKeyReferenceAware(key); - Object valueReference = delegate.remove(referenceAwareKey); - return valueReference == null ? null : (V) dereferenceValue(valueReference); - } - - public int size() { - return delegate.size(); - } - - public boolean isEmpty() { - return delegate.isEmpty(); - } - - public boolean containsKey(Object key) { - ensureNotNull(key); - Object referenceAwareKey = makeKeyReferenceAware(key); - return delegate.containsKey(referenceAwareKey); - } - - public boolean containsValue(Object value) { - ensureNotNull(value); - for (Object valueReference : delegate.values()) { - if (value.equals(dereferenceValue(valueReference))) { - return true; - } - } - return false; - } - - public void putAll(Map<? extends K, ? extends V> t) { - for (Map.Entry<? extends K, ? extends V> entry : t.entrySet()) { - put(entry.getKey(), entry.getValue()); - } - } - - public void clear() { - delegate.clear(); - } - - /** - * Returns an unmodifiable set view of the keys in this map. As this method - * creates a defensive copy, the performance is O(n). - */ - public Set<K> keySet() { - return Collections.unmodifiableSet(dereferenceKeySet(delegate.keySet())); - } - - /** - * Returns an unmodifiable set view of the values in this map. As this - * method creates a defensive copy, the performance is O(n). - */ - public Collection<V> values() { - return Collections.unmodifiableCollection(dereferenceValues(delegate.values())); - } - - public V putIfAbsent(K key, V value) { - // TODO (crazybob) if the value has been gc'ed but the entry hasn't been - // cleaned up yet, this put will fail. - return execute(putIfAbsentStrategy(), key, value); - } - - public boolean remove(Object key, Object value) { - ensureNotNull(key, value); - Object referenceAwareKey = makeKeyReferenceAware(key); - Object referenceAwareValue = makeValueReferenceAware(value); - return delegate.remove(referenceAwareKey, referenceAwareValue); - } - - public boolean replace(K key, V oldValue, V newValue) { - ensureNotNull(key, oldValue, newValue); - Object keyReference = referenceKey(key); - - Object referenceAwareOldValue = makeValueReferenceAware(oldValue); - return delegate.replace(keyReference, referenceAwareOldValue, referenceValue(keyReference, newValue)); - } - - public V replace(K key, V value) { - // TODO (crazybob) if the value has been gc'ed but the entry hasn't been - // cleaned up yet, this will succeed when it probably shouldn't. - return execute(replaceStrategy(), key, value); - } - - /** - * Returns an unmodifiable set view of the entries in this map. As this - * method creates a defensive copy, the performance is O(n). - */ - public Set<Map.Entry<K, V>> entrySet() { - Set<Map.Entry<K, V>> entrySet = new HashSet<>(); - for (Map.Entry<Object, Object> entry : delegate.entrySet()) { - Map.Entry<K, V> dereferenced = dereferenceEntry(entry); - if (dereferenced != null) { - entrySet.add(dereferenced); - } - } - return Collections.unmodifiableSet(entrySet); - } - - /** - * Dereferences an entry. Returns null if the key or value has been gc'ed. - */ - Entry dereferenceEntry(Map.Entry<Object, Object> entry) { - K key = dereferenceKey(entry.getKey()); - V value = dereferenceValue(entry.getValue()); - return (key == null || value == null) ? null : new Entry(key, value); - } - - /** - * Creates a reference for a key. - */ - Object referenceKey(K key) { - switch (keyReferenceType) { - case STRONG: - return key; - case SOFT: - return new SoftKeyReference(key); - case WEAK: - return new WeakKeyReference(key); - default: - throw new AssertionError(); - } - } - - /** - * Converts a reference to a key. - */ - K dereferenceKey(Object o) { - return (K) dereference(keyReferenceType, o); - } - - /** - * Converts a reference to a value. - */ - V dereferenceValue(Object o) { - return (V) dereference(valueReferenceType, o); - } - - /** - * Returns the refererent for reference given its reference type. - */ - Object dereference(ReferenceType referenceType, Object reference) { - return referenceType == STRONG ? reference : ((Reference) reference).get(); - } - - /** - * Creates a reference for a value. - */ - Object referenceValue(Object keyReference, Object value) { - switch (valueReferenceType) { - case STRONG: - return value; - case SOFT: - return new SoftValueReference(keyReference, value); - case WEAK: - return new WeakValueReference(keyReference, value); - default: - throw new AssertionError(); - } - } - - /** - * Dereferences a set of key references. - */ - Set<K> dereferenceKeySet(Set keyReferences) { - return keyReferenceType == STRONG - ? keyReferences - : dereferenceCollection(keyReferenceType, keyReferences, new HashSet()); - } - - /** - * Dereferences a collection of value references. - */ - Collection<V> dereferenceValues(Collection valueReferences) { - return valueReferenceType == STRONG - ? valueReferences - : dereferenceCollection(valueReferenceType, valueReferences, - new ArrayList(valueReferences.size())); - } - - /** - * Wraps key so it can be compared to a referenced key for equality. - */ - Object makeKeyReferenceAware(Object o) { - return keyReferenceType == STRONG ? o : new KeyReferenceAwareWrapper(o); - } - - /** - * Wraps value so it can be compared to a referenced value for equality. - */ - Object makeValueReferenceAware(Object o) { - return valueReferenceType == STRONG ? o : new ReferenceAwareWrapper(o); - } - - /** - * Dereferences elements in {@code in} using - * {@code referenceType} and puts them in {@code out}. Returns - * {@code out}. - */ - <T extends Collection<Object>> T dereferenceCollection(ReferenceType referenceType, T in, T out) { - for (Object reference : in) { - out.add(dereference(referenceType, reference)); - } - return out; - } - - /** - * Marker interface to differentiate external and internal references. - */ - interface InternalReference { - } - - static int keyHashCode(Object key) { - return System.identityHashCode(key); - } - - /** - * Tests weak and soft references for identity equality. Compares references - * to other references and wrappers. If o is a reference, this returns true - * if r == o or if r and o reference the same non null object. If o is a - * wrapper, this returns true if r's referent is identical to the wrapped - * object. - */ - static boolean referenceEquals(Reference r, Object o) { - // compare reference to reference. - if (o instanceof InternalReference) { - // are they the same reference? used in cleanup. - if (o == r) { - return true; - } - - // do they reference identical values? used in conditional puts. - Object referent = ((Reference) o).get(); - return referent != null && referent == r.get(); - } - - // is the wrapped object identical to the referent? used in lookups. - return ((ReferenceAwareWrapper) o).unwrap() == r.get(); - } - - /** - * Big hack. Used to compare keys and values to referenced keys and values - * without creating more references. - */ - static class ReferenceAwareWrapper { - - Object wrapped; - - ReferenceAwareWrapper(Object wrapped) { - this.wrapped = wrapped; - } - - Object unwrap() { - return wrapped; - } - - @Override - public int hashCode() { - return wrapped.hashCode(); - } - - @Override - public boolean equals(Object obj) { - // defer to reference's equals() logic. - return obj.equals(this); - } - } - - /** - * Used for keys. Overrides hash code to use identity hash code. - */ - static class KeyReferenceAwareWrapper extends ReferenceAwareWrapper { - - public KeyReferenceAwareWrapper(Object wrapped) { - super(wrapped); - } - - @Override - public int hashCode() { - return System.identityHashCode(wrapped); - } - } - - class SoftKeyReference extends FinalizableSoftReference<Object> implements InternalReference { - - int hashCode; - - public SoftKeyReference(Object key) { - super(key); - this.hashCode = keyHashCode(key); - } - - public void finalizeReferent() { - delegate.remove(this); - } - - @Override - public int hashCode() { - return this.hashCode; - } - - @Override - public boolean equals(Object o) { - return referenceEquals(this, o); - } - } - - class WeakKeyReference extends FinalizableWeakReference<Object> implements InternalReference { - - int hashCode; - - public WeakKeyReference(Object key) { - super(key); - this.hashCode = keyHashCode(key); - } - - public void finalizeReferent() { - delegate.remove(this); - } - - @Override - public int hashCode() { - return this.hashCode; - } - - @Override - public boolean equals(Object o) { - return referenceEquals(this, o); - } - } - - class SoftValueReference extends FinalizableSoftReference<Object> implements InternalReference { - - Object keyReference; - - public SoftValueReference(Object keyReference, Object value) { - super(value); - this.keyReference = keyReference; - } - - public void finalizeReferent() { - delegate.remove(keyReference, this); - } - - @Override - public boolean equals(Object obj) { - return referenceEquals(this, obj); - } - } - - class WeakValueReference extends FinalizableWeakReference<Object> implements InternalReference { - - Object keyReference; - - public WeakValueReference(Object keyReference, Object value) { - super(value); - this.keyReference = keyReference; - } - - public void finalizeReferent() { - delegate.remove(keyReference, this); - } - - @Override - public boolean equals(Object obj) { - return referenceEquals(this, obj); - } - } - - protected interface Strategy { - public Object execute(ReferenceMap map, Object keyReference, Object valueReference); - } - - protected Strategy putStrategy() { - return PutStrategy.PUT; - } - - protected Strategy putIfAbsentStrategy() { - return PutStrategy.PUT_IF_ABSENT; - } - - protected Strategy replaceStrategy() { - return PutStrategy.REPLACE; - } - - private enum PutStrategy implements Strategy { - PUT { - public Object execute(ReferenceMap map, Object keyReference, Object valueReference) { - return map.delegate.put(keyReference, valueReference); - } - }, - - REPLACE { - public Object execute(ReferenceMap map, Object keyReference, Object valueReference) { - return map.delegate.replace(keyReference, valueReference); - } - }, - - PUT_IF_ABSENT { - public Object execute(ReferenceMap map, Object keyReference, Object valueReference) { - return map.delegate.putIfAbsent(keyReference, valueReference); - } - }; - } - - private static PutStrategy defaultPutStrategy; - - protected PutStrategy getPutStrategy() { - return defaultPutStrategy; - } - - - class Entry implements Map.Entry<K, V> { - - K key; - V value; - - public Entry(K key, V value) { - this.key = key; - this.value = value; - } - - public K getKey() { - return this.key; - } - - public V getValue() { - return this.value; - } - - public V setValue(V value) { - return put(key, value); - } - - @Override - public int hashCode() { - return key.hashCode() * 31 + value.hashCode(); - } - - @Override - public boolean equals(Object o) { - if (!(o instanceof ReferenceMap.Entry)) { - return false; - } - - Entry entry = (Entry) o; - return key.equals(entry.key) && value.equals(entry.value); - } - - @Override - public String toString() { - return key + "=" + value; - } - } - - static void ensureNotNull(Object o) { - if (o == null) { - throw new NullPointerException(); - } - } - - static void ensureNotNull(Object... array) { - for (int i = 0; i < array.length; i++) { - if (array[i] == null) { - throw new NullPointerException("Argument #" + i + " is null."); - } - } - } - - private void writeObject(ObjectOutputStream out) throws IOException { - out.defaultWriteObject(); - out.writeInt(size()); - for (Map.Entry<Object, Object> entry : delegate.entrySet()) { - Object key = dereferenceKey(entry.getKey()); - Object value = dereferenceValue(entry.getValue()); - - // don't persist gc'ed entries. - if (key != null && value != null) { - out.writeObject(key); - out.writeObject(value); - } - } - out.writeObject(null); - } - - private void readObject(ObjectInputStream in) throws IOException, - ClassNotFoundException { - in.defaultReadObject(); - int size = in.readInt(); - this.delegate = new ConcurrentHashMap<Object, Object>(size); - while (true) { - K key = (K) in.readObject(); - if (key == null) { - break; - } - V value = (V) in.readObject(); - put(key, value); - } - } - -} http://git-wip-us.apache.org/repos/asf/struts/blob/31af5842/xwork-core/src/main/java/com/opensymphony/xwork2/inject/util/ReferenceType.java ---------------------------------------------------------------------- diff --git a/xwork-core/src/main/java/com/opensymphony/xwork2/inject/util/ReferenceType.java b/xwork-core/src/main/java/com/opensymphony/xwork2/inject/util/ReferenceType.java deleted file mode 100644 index a223a00..0000000 --- a/xwork-core/src/main/java/com/opensymphony/xwork2/inject/util/ReferenceType.java +++ /dev/null @@ -1,55 +0,0 @@ -/** - * Copyright (C) 2006 Google Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.opensymphony.xwork2.inject.util; - -/** - * Reference type. Used to specify what type of reference to keep to a - * referent. - * - * @see java.lang.ref.Reference - * @author [email protected] (Bob Lee) - */ -public enum ReferenceType { - - /** - * Prevents referent from being reclaimed by the garbage collector. - */ - STRONG, - - /** - * Referent reclaimed in an LRU fashion when the VM runs low on memory and - * no strong references exist. - * - * @see java.lang.ref.SoftReference - */ - SOFT, - - /** - * Referent reclaimed when no strong or soft references exist. - * - * @see java.lang.ref.WeakReference - */ - WEAK, - - /** - * Similar to weak references except the garbage collector doesn't actually - * reclaim the referent. More flexible alternative to finalization. - * - * @see java.lang.ref.PhantomReference - */ - PHANTOM; -} http://git-wip-us.apache.org/repos/asf/struts/blob/31af5842/xwork-core/src/main/java/com/opensymphony/xwork2/inject/util/Strings.java ---------------------------------------------------------------------- diff --git a/xwork-core/src/main/java/com/opensymphony/xwork2/inject/util/Strings.java b/xwork-core/src/main/java/com/opensymphony/xwork2/inject/util/Strings.java deleted file mode 100644 index a15291a..0000000 --- a/xwork-core/src/main/java/com/opensymphony/xwork2/inject/util/Strings.java +++ /dev/null @@ -1,55 +0,0 @@ -/** - * Copyright (C) 2006 Google Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.opensymphony.xwork2.inject.util; - -/** - * String utilities. - * - * @author [email protected] (Bob Lee) - */ -public class Strings { - - /** - * Returns a string that is equivalent to the specified string with its - * first character converted to uppercase as by {@link String#toUpperCase}. - * The returned string will have the same value as the specified string if - * its first character is non-alphabetic, if its first character is already - * uppercase, or if the specified string is of length 0. - * - * <p>For example: - * <pre> - * capitalize("foo bar").equals("Foo bar"); - * capitalize("2b or not 2b").equals("2b or not 2b") - * capitalize("Foo bar").equals("Foo bar"); - * capitalize("").equals(""); - * </pre> - * - * @param s the string whose first character is to be uppercased - * @return a string equivalent to <tt>s</tt> with its first character - * converted to uppercase - * @throws NullPointerException if <tt>s</tt> is null - */ - public static String capitalize(String s) { - if (s.length() == 0) - return s; - char first = s.charAt(0); - char capitalized = Character.toUpperCase(first); - return (first == capitalized) - ? s - : capitalized + s.substring(1); - } -} http://git-wip-us.apache.org/repos/asf/struts/blob/31af5842/xwork-core/src/main/java/com/opensymphony/xwork2/inject/util/package.html ---------------------------------------------------------------------- diff --git a/xwork-core/src/main/java/com/opensymphony/xwork2/inject/util/package.html b/xwork-core/src/main/java/com/opensymphony/xwork2/inject/util/package.html deleted file mode 100644 index e326461..0000000 --- a/xwork-core/src/main/java/com/opensymphony/xwork2/inject/util/package.html +++ /dev/null @@ -1 +0,0 @@ -<body>Guice util classes.</body> http://git-wip-us.apache.org/repos/asf/struts/blob/31af5842/xwork-core/src/main/java/com/opensymphony/xwork2/interceptor/AbstractInterceptor.java ---------------------------------------------------------------------- diff --git a/xwork-core/src/main/java/com/opensymphony/xwork2/interceptor/AbstractInterceptor.java b/xwork-core/src/main/java/com/opensymphony/xwork2/interceptor/AbstractInterceptor.java deleted file mode 100644 index 470d349..0000000 --- a/xwork-core/src/main/java/com/opensymphony/xwork2/interceptor/AbstractInterceptor.java +++ /dev/null @@ -1,42 +0,0 @@ -/* - * Copyright 2002-2006,2009 The Apache Software Foundation. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.opensymphony.xwork2.interceptor; - -import com.opensymphony.xwork2.ActionInvocation; - -/** - * Provides default implementations of optional lifecycle methods - */ -public abstract class AbstractInterceptor implements Interceptor { - - /** - * Does nothing - */ - public void init() { - } - - /** - * Does nothing - */ - public void destroy() { - } - - - /** - * Override to handle interception - */ - public abstract String intercept(ActionInvocation invocation) throws Exception; -} http://git-wip-us.apache.org/repos/asf/struts/blob/31af5842/xwork-core/src/main/java/com/opensymphony/xwork2/interceptor/AliasInterceptor.java ---------------------------------------------------------------------- diff --git a/xwork-core/src/main/java/com/opensymphony/xwork2/interceptor/AliasInterceptor.java b/xwork-core/src/main/java/com/opensymphony/xwork2/interceptor/AliasInterceptor.java deleted file mode 100644 index 7bd9499..0000000 --- a/xwork-core/src/main/java/com/opensymphony/xwork2/interceptor/AliasInterceptor.java +++ /dev/null @@ -1,194 +0,0 @@ -/* - * Copyright 2002-2006,2009 The Apache Software Foundation. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.opensymphony.xwork2.interceptor; - -import com.opensymphony.xwork2.ActionContext; -import com.opensymphony.xwork2.ActionInvocation; -import com.opensymphony.xwork2.ValidationAware; -import com.opensymphony.xwork2.XWorkConstants; -import com.opensymphony.xwork2.config.entities.ActionConfig; -import com.opensymphony.xwork2.inject.Inject; -import com.opensymphony.xwork2.util.ClearableValueStack; -import com.opensymphony.xwork2.util.LocalizedTextUtil; -import com.opensymphony.xwork2.util.ValueStack; -import com.opensymphony.xwork2.util.ValueStackFactory; -import com.opensymphony.xwork2.util.reflection.ReflectionContextState; -import org.apache.logging.log4j.LogManager; -import org.apache.logging.log4j.Logger; - -import java.util.Map; - - -/** - * <!-- START SNIPPET: description --> - * - * The aim of this Interceptor is to alias a named parameter to a different named parameter. By acting as the glue - * between actions sharing similiar parameters (but with different names), it can help greatly with action chaining. - * - * <p/> Action's alias expressions should be in the form of <code>#{ "name1" : "alias1", "name2" : "alias2" }</code>. - * This means that assuming an action (or something else in the stack) has a value for the expression named <i>name1</i> and the - * action this interceptor is applied to has a setter named <i>alias1</i>, <i>alias1</i> will be set with the value from - * <i>name1</i>. - * - * <!-- END SNIPPET: description --> - * - * <p/> <u>Interceptor parameters:</u> - * - * <!-- START SNIPPET: parameters --> - * - * <ul> - * - * <li>aliasesKey (optional) - the name of the action parameter to look for the alias map (by default this is - * <i>aliases</i>).</li> - * - * </ul> - * - * <!-- END SNIPPET: parameters --> - * - * <p/> <u>Extending the interceptor:</u> - * - * <p/> - * - * <!-- START SNIPPET: extending --> - * - * This interceptor does not have any known extension points. - * - * <!-- END SNIPPET: extending --> - * - * <p/> <u>Example code:</u> - * - * <pre> - * <!-- START SNIPPET: example --> - * <action name="someAction" class="com.examples.SomeAction"> - * <!-- The value for the foo parameter will be applied as if it were named bar --> - * <param name="aliases">#{ 'foo' : 'bar' }</param> - * - * <interceptor-ref name="alias"/> - * <interceptor-ref name="basicStack"/> - * <result name="success">good_result.ftl</result> - * </action> - * <!-- END SNIPPET: example --> - * </pre> - * - * @author Matthew Payne - */ -public class AliasInterceptor extends AbstractInterceptor { - - private static final Logger LOG = LogManager.getLogger(AliasInterceptor.class); - - private static final String DEFAULT_ALIAS_KEY = "aliases"; - protected String aliasesKey = DEFAULT_ALIAS_KEY; - - protected ValueStackFactory valueStackFactory; - static boolean devMode = false; - - @Inject(XWorkConstants.DEV_MODE) - public static void setDevMode(String mode) { - devMode = "true".equals(mode); - } - - @Inject - public void setValueStackFactory(ValueStackFactory valueStackFactory) { - this.valueStackFactory = valueStackFactory; - } - - /** - * Sets the name of the action parameter to look for the alias map. - * <p/> - * Default is <code>aliases</code>. - * - * @param aliasesKey the name of the action parameter - */ - public void setAliasesKey(String aliasesKey) { - this.aliasesKey = aliasesKey; - } - - @Override public String intercept(ActionInvocation invocation) throws Exception { - - ActionConfig config = invocation.getProxy().getConfig(); - ActionContext ac = invocation.getInvocationContext(); - Object action = invocation.getAction(); - - // get the action's parameters - final Map<String, String> parameters = config.getParams(); - - if (parameters.containsKey(aliasesKey)) { - - String aliasExpression = parameters.get(aliasesKey); - ValueStack stack = ac.getValueStack(); - Object obj = stack.findValue(aliasExpression); - - if (obj != null && obj instanceof Map) { - //get secure stack - ValueStack newStack = valueStackFactory.createValueStack(stack); - boolean clearableStack = newStack instanceof ClearableValueStack; - if (clearableStack) { - //if the stack's context can be cleared, do that to prevent OGNL - //from having access to objects in the stack, see XW-641 - ((ClearableValueStack)newStack).clearContextValues(); - Map<String, Object> context = newStack.getContext(); - ReflectionContextState.setCreatingNullObjects(context, true); - ReflectionContextState.setDenyMethodExecution(context, true); - ReflectionContextState.setReportingConversionErrors(context, true); - - //keep locale from original context - context.put(ActionContext.LOCALE, stack.getContext().get(ActionContext.LOCALE)); - } - - // override - Map aliases = (Map) obj; - for (Object o : aliases.entrySet()) { - Map.Entry entry = (Map.Entry) o; - String name = entry.getKey().toString(); - String alias = (String) entry.getValue(); - Object value = stack.findValue(name); - if (null == value) { - // workaround - Map<String, Object> contextParameters = ActionContext.getContext().getParameters(); - - if (null != contextParameters) { - value = contextParameters.get(name); - } - } - if (null != value) { - try { - newStack.setValue(alias, value); - } catch (RuntimeException e) { - if (devMode) { - String developerNotification = LocalizedTextUtil.findText(ParametersInterceptor.class, "devmode.notification", ActionContext.getContext().getLocale(), "Developer Notification:\n{0}", new Object[]{ - "Unexpected Exception caught setting '" + entry.getKey() + "' on '" + action.getClass() + ": " + e.getMessage() - }); - LOG.error(developerNotification); - if (action instanceof ValidationAware) { - ((ValidationAware) action).addActionMessage(developerNotification); - } - } - } - } - } - - if (clearableStack && (stack.getContext() != null) && (newStack.getContext() != null)) - stack.getContext().put(ActionContext.CONVERSION_ERRORS, newStack.getContext().get(ActionContext.CONVERSION_ERRORS)); - } else { - LOG.debug("invalid alias expression: {}", aliasesKey); - } - } - - return invocation.invoke(); - } - -} http://git-wip-us.apache.org/repos/asf/struts/blob/31af5842/xwork-core/src/main/java/com/opensymphony/xwork2/interceptor/ChainingInterceptor.java ---------------------------------------------------------------------- diff --git a/xwork-core/src/main/java/com/opensymphony/xwork2/interceptor/ChainingInterceptor.java b/xwork-core/src/main/java/com/opensymphony/xwork2/interceptor/ChainingInterceptor.java deleted file mode 100644 index 8218e1b..0000000 --- a/xwork-core/src/main/java/com/opensymphony/xwork2/interceptor/ChainingInterceptor.java +++ /dev/null @@ -1,230 +0,0 @@ -/* - * Copyright 2002-2007,2009 The Apache Software Foundation. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.opensymphony.xwork2.interceptor; - -import com.opensymphony.xwork2.ActionChainResult; -import com.opensymphony.xwork2.ActionInvocation; -import com.opensymphony.xwork2.Result; -import com.opensymphony.xwork2.Unchainable; -import com.opensymphony.xwork2.inject.Inject; -import com.opensymphony.xwork2.util.CompoundRoot; -import com.opensymphony.xwork2.util.ValueStack; -import org.apache.logging.log4j.Logger; -import org.apache.logging.log4j.LogManager; -import com.opensymphony.xwork2.util.reflection.ReflectionProvider; - -import java.util.*; - - -/** - * <!-- START SNIPPET: description --> - * <p/> - * An interceptor that copies all the properties of every object in the value stack to the currently executing object, - * except for any object that implements {@link Unchainable}. A collection of optional <i>includes</i> and - * <i>excludes</i> may be provided to control how and which parameters are copied. Only includes or excludes may be - * specified. Specifying both results in undefined behavior. See the javadocs for {@link ReflectionProvider#copy(Object, Object, - * java.util.Map, java.util.Collection, java.util.Collection)} for more information. - * <p/> - * <p/> - * <b>Note:</b> It is important to remember that this interceptor does nothing if there are no objects already on the stack. - * <br/>This means two things: - * <br/><b>One</b>, you can safely apply it to all your actions without any worry of adverse affects. - * <br/><b/>Two</b>, it is up to you to ensure an object exists in the stack prior to invoking this action. The most typical way this is done - * is through the use of the <b>chain</b> result type, which combines with this interceptor to make up the action - * chaining feature. - * <p/> - * <b>Note:</b> By default Errors, Field errors and Message aren't copied during chaining, to change the behaviour you can specify - * the below three constants in struts.properties or struts.xml: - * <ul> - * <li>struts.xwork.chaining.copyErrors - set to true to copy Action Errors</li> - * <li>struts.xwork.chaining.copyFieldErrors - set to true to copy Field Errors</li> - * <li>struts.xwork.chaining.copyMessages - set to true to copy Action Messages</li> - * </ul> - * <p> - * <p> - * <u>Example:</u> - * <pre> - * <constant name="struts.xwork.chaining.copyErrors" value="true"/> - * </pre> - * </p> - * <b>Note:</b> By default actionErrors and actionMessages are excluded when copping object's properties. - * </p> - * <!-- END SNIPPET: description --> - * <u>Interceptor parameters:</u> - * <!-- START SNIPPET: parameters --> - * <ul> - * <li>excludes (optional) - the list of parameter names to exclude from copying (all others will be included).</li> - * <li>includes (optional) - the list of parameter names to include when copying (all others will be excluded).</li> - * </ul> - * <!-- END SNIPPET: parameters --> - * <u>Extending the interceptor:</u> - * <!-- START SNIPPET: extending --> - * <p> - * There are no known extension points to this interceptor. - * </p> - * <!-- END SNIPPET: extending --> - * <u>Example code:</u> - * <pre> - * <!-- START SNIPPET: example --> - * <p/> - * <action name="someAction" class="com.examples.SomeAction"> - * <interceptor-ref name="basicStack"/> - * <result name="success" type="chain">otherAction</result> - * </action> - * <p/> - * <action name="otherAction" class="com.examples.OtherAction"> - * <interceptor-ref name="chain"/> - * <interceptor-ref name="basicStack"/> - * <result name="success">good_result.ftl</result> - * </action> - * <p/> - * <!-- END SNIPPET: example --> - * </pre> - * - * @author mrdon - * @author tm_jee ( tm_jee(at)yahoo.co.uk ) - * @see com.opensymphony.xwork2.ActionChainResult - */ -public class ChainingInterceptor extends AbstractInterceptor { - - private static final Logger LOG = LogManager.getLogger(ChainingInterceptor.class); - - private static final String ACTION_ERRORS = "actionErrors"; - private static final String FIELD_ERRORS = "fieldErrors"; - private static final String ACTION_MESSAGES = "actionMessages"; - - private boolean copyMessages = false; - private boolean copyErrors = false; - private boolean copyFieldErrors = false; - - protected Collection<String> excludes; - - protected Collection<String> includes; - protected ReflectionProvider reflectionProvider; - - @Inject - public void setReflectionProvider(ReflectionProvider prov) { - this.reflectionProvider = prov; - } - - @Inject(value = "struts.xwork.chaining.copyErrors", required = false) - public void setCopyErrors(String copyErrors) { - this.copyErrors = "true".equalsIgnoreCase(copyErrors); - } - - @Inject(value = "struts.xwork.chaining.copyFieldErrors", required = false) - public void setCopyFieldErrors(String copyFieldErrors) { - this.copyFieldErrors = "true".equalsIgnoreCase(copyFieldErrors); - } - - @Inject(value = "struts.xwork.chaining.copyMessages", required = false) - public void setCopyMessages(String copyMessages) { - this.copyMessages = "true".equalsIgnoreCase(copyMessages); - } - - @Override - public String intercept(ActionInvocation invocation) throws Exception { - ValueStack stack = invocation.getStack(); - CompoundRoot root = stack.getRoot(); - if (shouldCopyStack(invocation, root)) { - copyStack(invocation, root); - } - return invocation.invoke(); - } - - private void copyStack(ActionInvocation invocation, CompoundRoot root) { - List list = prepareList(root); - Map<String, Object> ctxMap = invocation.getInvocationContext().getContextMap(); - for (Object object : list) { - if (shouldCopy(object)) { - reflectionProvider.copy(object, invocation.getAction(), ctxMap, prepareExcludes(), includes); - } - } - } - - private Collection<String> prepareExcludes() { - Collection<String> localExcludes = excludes; - if (!copyErrors || !copyMessages ||!copyFieldErrors) { - if (localExcludes == null) { - localExcludes = new HashSet<String>(); - if (!copyErrors) { - localExcludes.add(ACTION_ERRORS); - } - if (!copyMessages) { - localExcludes.add(ACTION_MESSAGES); - } - if (!copyFieldErrors) { - localExcludes.add(FIELD_ERRORS); - } - } - } - return localExcludes; - } - - private boolean shouldCopy(Object o) { - return o != null && !(o instanceof Unchainable); - } - - @SuppressWarnings("unchecked") - private List prepareList(CompoundRoot root) { - List list = new ArrayList(root); - list.remove(0); - Collections.reverse(list); - return list; - } - - private boolean shouldCopyStack(ActionInvocation invocation, CompoundRoot root) throws Exception { - Result result = invocation.getResult(); - return root.size() > 1 && (result == null || ActionChainResult.class.isAssignableFrom(result.getClass())); - } - - /** - * Gets list of parameter names to exclude - * - * @return the exclude list - */ - public Collection<String> getExcludes() { - return excludes; - } - - /** - * Sets the list of parameter names to exclude from copying (all others will be included). - * - * @param excludes the excludes list - */ - public void setExcludes(Collection<String> excludes) { - this.excludes = excludes; - } - - /** - * Gets list of parameter names to include - * - * @return the include list - */ - public Collection<String> getIncludes() { - return includes; - } - - /** - * Sets the list of parameter names to include when copying (all others will be excluded). - * - * @param includes the includes list - */ - public void setIncludes(Collection<String> includes) { - this.includes = includes; - } - -} http://git-wip-us.apache.org/repos/asf/struts/blob/31af5842/xwork-core/src/main/java/com/opensymphony/xwork2/interceptor/ConversionErrorInterceptor.java ---------------------------------------------------------------------- diff --git a/xwork-core/src/main/java/com/opensymphony/xwork2/interceptor/ConversionErrorInterceptor.java b/xwork-core/src/main/java/com/opensymphony/xwork2/interceptor/ConversionErrorInterceptor.java deleted file mode 100644 index 47d020a..0000000 --- a/xwork-core/src/main/java/com/opensymphony/xwork2/interceptor/ConversionErrorInterceptor.java +++ /dev/null @@ -1,144 +0,0 @@ -/* - * Copyright 2002-2007,2009 The Apache Software Foundation. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.opensymphony.xwork2.interceptor; - -import com.opensymphony.xwork2.ActionContext; -import com.opensymphony.xwork2.ActionInvocation; -import com.opensymphony.xwork2.ValidationAware; -import com.opensymphony.xwork2.conversion.impl.XWorkConverter; -import com.opensymphony.xwork2.util.ValueStack; -import org.apache.commons.lang3.StringEscapeUtils; - -import java.util.HashMap; -import java.util.Map; - - -/** - * <!-- START SNIPPET: description --> - * ConversionErrorInterceptor adds conversion errors from the ActionContext to the Action's field errors. - * - * <p/> - * This interceptor adds any error found in the {@link ActionContext}'s conversionErrors map as a field error (provided - * that the action implements {@link ValidationAware}). In addition, any field that contains a validation error has its - * original value saved such that any subsequent requests for that value return the original value rather than the value - * in the action. This is important because if the value "abc" is submitted and can't be converted to an int, we want to - * display the original string ("abc") again rather than the int value (likely 0, which would make very little sense to - * the user). - * - * - * <!-- END SNIPPET: description --> - * - * <p/> <u>Interceptor parameters:</u> - * - * <!-- START SNIPPET: parameters --> - * - * <ul> - * - * <li>None</li> - * - * </ul> - * - * <!-- END SNIPPET: parameters --> - * - * <p/> <u>Extending the interceptor:</u> - * - * <p/> - * - * <!-- START SNIPPET: extending --> - * - * Because this interceptor is not web-specific, it abstracts the logic for whether an error should be added. This - * allows for web-specific interceptors to use more complex logic in the {@link #shouldAddError} method for when a value - * has a conversion error but is null or empty or otherwise indicates that the value was never actually entered by the - * user. - * - * <!-- END SNIPPET: extending --> - * - * <p/> <u>Example code:</u> - * - * <pre> - * <!-- START SNIPPET: example --> - * <action name="someAction" class="com.examples.SomeAction"> - * <interceptor-ref name="params"/> - * <interceptor-ref name="conversionError"/> - * <result name="success">good_result.ftl</result> - * </action> - * <!-- END SNIPPET: example --> - * </pre> - * - * @author Jason Carreira - */ -public class ConversionErrorInterceptor extends AbstractInterceptor { - - public static final String ORIGINAL_PROPERTY_OVERRIDE = "original.property.override"; - - protected Object getOverrideExpr(ActionInvocation invocation, Object value) { - return escape(value); - } - - protected String escape(Object value) { - return "\"" + StringEscapeUtils.escapeJava(String.valueOf(value)) + "\""; - } - - @Override - public String intercept(ActionInvocation invocation) throws Exception { - - ActionContext invocationContext = invocation.getInvocationContext(); - Map<String, Object> conversionErrors = invocationContext.getConversionErrors(); - ValueStack stack = invocationContext.getValueStack(); - - HashMap<Object, Object> fakie = null; - - for (Map.Entry<String, Object> entry : conversionErrors.entrySet()) { - String propertyName = entry.getKey(); - Object value = entry.getValue(); - - if (shouldAddError(propertyName, value)) { - String message = XWorkConverter.getConversionErrorMessage(propertyName, stack); - - Object action = invocation.getAction(); - if (action instanceof ValidationAware) { - ValidationAware va = (ValidationAware) action; - va.addFieldError(propertyName, message); - } - - if (fakie == null) { - fakie = new HashMap<>(); - } - - fakie.put(propertyName, getOverrideExpr(invocation, value)); - } - } - - if (fakie != null) { - // if there were some errors, put the original (fake) values in place right before the result - stack.getContext().put(ORIGINAL_PROPERTY_OVERRIDE, fakie); - invocation.addPreResultListener(new PreResultListener() { - public void beforeResult(ActionInvocation invocation, String resultCode) { - Map<Object, Object> fakie = (Map<Object, Object>) invocation.getInvocationContext().get(ORIGINAL_PROPERTY_OVERRIDE); - - if (fakie != null) { - invocation.getStack().setExprOverrides(fakie); - } - } - }); - } - return invocation.invoke(); - } - - protected boolean shouldAddError(String propertyName, Object value) { - return true; - } -}
