View Javadoc

1   /*
2    * Copyright 2004-2005, 2007 the original author or authors.
3    *
4    * Licensed under the Apache License, Version 2.0 (the "License"); you may not
5    * use this file except in compliance with the License. You may obtain a copy of
6    * the License at
7    *
8    * http://www.apache.org/licenses/LICENSE-2.0
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12   * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13   * License for the specific language governing permissions and limitations under
14   * the License.
15   */
16  package net.sf.composite.specialize.specializers;
17  
18  import net.sf.composite.Defaults;
19  import net.sf.composite.extract.ComponentAccessor;
20  import net.sf.composite.specialize.SpecializationException;
21  import net.sf.composite.specialize.Specializer;
22  import net.sf.composite.util.Assert;
23  import net.sf.composite.util.ObjectUtils;
24  
25  import org.apache.commons.logging.Log;
26  import org.apache.commons.logging.LogFactory;
27  
28  /***
29   * A convenient base class for specializers.  This base class takes care
30   * of exception handling, argument validation and logging.
31   *
32   * @author Matt Sgarlata
33   * @since Mar 11, 2005
34   */
35  public abstract class BaseSpecializer implements Specializer {
36  
37  	protected final Log log = LogFactory.getLog(getClass());
38  
39  	private ComponentAccessor componentAccessor;
40  
41  	/***
42  	 * Implementation template method.
43  	 * @param composite
44  	 * @param specializedType
45  	 * @return boolean
46  	 * @throws Exception
47  	 */
48  	protected abstract boolean isSpecializableImpl(Object composite, Class specializedType) throws Exception;
49  
50  	private boolean isSpecializableInternal(Object composite,
51  		Class specializedType) {
52  
53  		try {
54  			return isSpecializableImpl(composite, specializedType);
55  		}
56  		catch (SpecializationException e) {
57  			throw e;
58  		}
59  		catch (Exception e) {
60  			throw new SpecializationException(
61  				"Unable to determine if composite "
62  					+ ObjectUtils.getObjectDescription(composite)
63  					+ " is specializable to type "
64  					+ ObjectUtils.getObjectDescription(specializedType));
65  		}
66  	}
67  
68  	public final boolean isSpecializable(Object composite, Class specializedType) throws SpecializationException {
69  		Assert.notNull(composite, "composite");
70  
71  		boolean isSpecializable = isSpecializableInternal(composite,
72  			specializedType);
73  
74  		if (log.isTraceEnabled()) {
75  			log.trace("composite "
76  				+ ObjectUtils.getObjectDescription(composite)
77  				+ (isSpecializable ? "is" : "is not")
78  				+ " specializable to type "
79  				+ ObjectUtils.getObjectDescription(specializedType));
80  		}
81  		return isSpecializable;
82  	}
83  
84  	protected abstract Object specializeImpl(Object composite, Class specializedType) throws Exception;
85  
86  	public final Object specialize(Object composite, Class specializedType) throws SpecializationException {
87  		Assert.notNull(composite, "composite");
88  
89  		try {
90  			if (!isSpecializableInternal(composite, specializedType)) {
91  				throw new SpecializationException("composite "
92  					+ ObjectUtils.getObjectDescription(composite)
93  					+ " is not specializable to type "
94  					+ ObjectUtils.getObjectDescription(specializedType));
95  			}
96  
97  			if (ObjectUtils.isEmpty(getComponentAccessor().getComponents(composite))) {
98  				throw new SpecializationException(
99  					"Unable to specialize composite "
100 						+ ObjectUtils.getObjectDescription(composite)
101 						+ " because it contains no components of type "
102 						+ ObjectUtils.getObjectDescription(specializedType));
103 			}
104 
105 			Object specialized = specializeImpl(composite, specializedType);
106 
107 			if (log.isTraceEnabled()) {
108 				log.trace("Created specialized composite "
109 					+ ObjectUtils.getObjectDescription(specialized)
110 					+ " of type "
111 					+ ObjectUtils.getObjectDescription(specializedType)
112 					+ " from composite "
113 					+ ObjectUtils.getObjectDescription(composite));
114 			}
115 			return specialized;
116 		}
117 		catch (SpecializationException e) {
118 			throw e;
119 		}
120 		catch (Exception e) {
121 			throw new SpecializationException(
122 				"Unable to specialize composite "
123 					+ ObjectUtils.getObjectDescription(composite)
124 					+ " to type "
125 					+ ObjectUtils.getObjectDescription(specializedType), e);
126 		}
127 	}
128 
129 	public synchronized ComponentAccessor getComponentAccessor() {
130 		if (componentAccessor == null) {
131 			setComponentAccessor(Defaults.createComponentAccessor());
132 		}
133 		return componentAccessor;
134 	}
135 
136 	public synchronized void setComponentAccessor(ComponentAccessor componentExtractor) {
137 		this.componentAccessor = componentExtractor;
138 	}
139 
140 }