01: /*
02: * Copyright (c) 2007, 2008 XStream Committers.
03: * All rights reserved.
04: *
05: * The software in this package is published under the terms of the BSD
06: * style license a copy of which has been included with this distribution in
07: * the LICENSE.txt file.
08: *
09: * Created on 20. September 2007 by Joerg Schaible
10: */
11: package com.thoughtworks.xstream.core.util;
12:
13: import com.thoughtworks.xstream.converters.reflection.ObjectAccessException;
14:
15: import java.beans.PropertyEditor;
16:
17: /**
18: * Wrapper around {@link PropertyEditor} that can be called by multiple threads concurrently.
19: * <p>
20: * A PropertyEditor is not thread safe. To make best use of resources, the PropertyEditor
21: * provides a dynamically sizing pool of instances, each of which will only be called by a
22: * single thread at a time.
23: * </p>
24: * <p>
25: * The pool has a maximum capacity, to limit overhead. If all instances in the pool are in use
26: * and another is required, it shall block until one becomes available.
27: * </p>
28: *
29: * @author Jörg Schaible
30: * @since 1.3
31: */
32: public class ThreadSafePropertyEditor {
33:
34: private final Class editorType;
35: private final Pool pool;
36:
37: public ThreadSafePropertyEditor(Class type, int initialPoolSize,
38: int maxPoolSize) {
39: if (!PropertyEditor.class.isAssignableFrom(type)) {
40: throw new IllegalArgumentException(type.getName()
41: + " is not a " + PropertyEditor.class.getName());
42: }
43: editorType = type;
44: pool = new Pool(initialPoolSize, maxPoolSize,
45: new Pool.Factory() {
46: public Object newInstance() {
47: try {
48: return editorType.newInstance();
49: } catch (InstantiationException e) {
50: throw new ObjectAccessException(
51: "Could not call default constructor of "
52: + editorType.getName(), e);
53: } catch (IllegalAccessException e) {
54: throw new ObjectAccessException(
55: "Could not call default constructor of "
56: + editorType.getName(), e);
57: }
58: }
59:
60: });
61: }
62:
63: public String getAsText(Object object) {
64: PropertyEditor editor = fetchFromPool();
65: try {
66: editor.setValue(object);
67: return editor.getAsText();
68: } finally {
69: pool.putInPool(editor);
70: }
71: }
72:
73: public Object setAsText(String str) {
74: PropertyEditor editor = fetchFromPool();
75: try {
76: editor.setAsText(str);
77: return editor.getValue();
78: } finally {
79: pool.putInPool(editor);
80: }
81: }
82:
83: private PropertyEditor fetchFromPool() {
84: PropertyEditor editor = (PropertyEditor) pool.fetchFromPool();
85: return editor;
86: }
87: }
|