001: // Copyright 2006, 2007 The Apache Software Foundation
002: //
003: // Licensed under the Apache License, Version 2.0 (the "License");
004: // you may not use this file except in compliance with the License.
005: // You may obtain a copy of the License at
006: //
007: // http://www.apache.org/licenses/LICENSE-2.0
008: //
009: // Unless required by applicable law or agreed to in writing, software
010: // distributed under the License is distributed on an "AS IS" BASIS,
011: // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
012: // See the License for the specific language governing permissions and
013: // limitations under the License.
014:
015: package org.apache.tapestry.internal.services;
016:
017: import org.apache.tapestry.annotations.Component;
018: import org.apache.tapestry.annotations.MixinClasses;
019: import org.apache.tapestry.annotations.Mixins;
020: import org.apache.tapestry.internal.KeyValue;
021: import org.apache.tapestry.internal.TapestryInternalUtils;
022: import org.apache.tapestry.ioc.Location;
023: import org.apache.tapestry.ioc.internal.services.StringLocation;
024: import org.apache.tapestry.ioc.internal.util.InternalUtils;
025: import org.apache.tapestry.model.ComponentModel;
026: import org.apache.tapestry.model.MutableComponentModel;
027: import org.apache.tapestry.model.MutableEmbeddedComponentModel;
028: import org.apache.tapestry.services.ClassTransformation;
029: import org.apache.tapestry.services.ComponentClassResolver;
030: import org.apache.tapestry.services.ComponentClassTransformWorker;
031: import org.apache.tapestry.services.TransformConstants;
032:
033: /**
034: * Finds fields with the {@link org.apache.tapestry.annotations.Component} annotation and updates
035: * the model. Also checks for the {@link Mixins} and {@link MixinClasses} annotations and uses them
036: * to update the {@link ComponentModel}.
037: */
038: public class ComponentWorker implements ComponentClassTransformWorker {
039: private final ComponentClassResolver _resolver;
040:
041: public ComponentWorker(final ComponentClassResolver resolver) {
042: _resolver = resolver;
043: }
044:
045: public void transform(ClassTransformation transformation,
046: MutableComponentModel model) {
047: for (String fieldName : transformation
048: .findFieldsWithAnnotation(Component.class)) {
049: Component annotation = transformation.getFieldAnnotation(
050: fieldName, Component.class);
051:
052: String id = annotation.id();
053:
054: if (InternalUtils.isBlank(id))
055: id = InternalUtils.stripMemberPrefix(fieldName);
056:
057: String type = transformation.getFieldType(fieldName);
058:
059: Location location = new StringLocation(String.format(
060: "%s.%s", transformation.getClassName(), fieldName),
061: 0);
062:
063: MutableEmbeddedComponentModel embedded = model
064: .addEmbeddedComponent(id, annotation.type(), type,
065: location);
066:
067: addParameters(embedded, annotation.parameters());
068:
069: transformation.makeReadOnly(fieldName);
070:
071: String body = String.format(
072: "%s = (%s) %s.getEmbeddedComponent(\"%s\");",
073: fieldName, type, transformation
074: .getResourcesFieldName(), id);
075:
076: transformation
077: .extendMethod(
078: TransformConstants.CONTAINING_PAGE_DID_LOAD_SIGNATURE,
079: body);
080:
081: addMixinClasses(fieldName, transformation, embedded);
082: addMixinTypes(fieldName, transformation, embedded);
083:
084: transformation.claimField(fieldName, annotation);
085: }
086: }
087:
088: private void addMixinClasses(String fieldName,
089: ClassTransformation transformation,
090: MutableEmbeddedComponentModel model) {
091: MixinClasses annotation = transformation.getFieldAnnotation(
092: fieldName, MixinClasses.class);
093:
094: if (annotation == null)
095: return;
096:
097: for (Class c : annotation.value())
098: model.addMixin(c.getName());
099: }
100:
101: private void addMixinTypes(String fieldName,
102: ClassTransformation transformation,
103: MutableEmbeddedComponentModel model) {
104: Mixins annotation = transformation.getFieldAnnotation(
105: fieldName, Mixins.class);
106:
107: if (annotation == null)
108: return;
109:
110: for (String typeName : annotation.value()) {
111: String mixinClassName = _resolver
112: .resolveMixinTypeToClassName(typeName);
113: model.addMixin(mixinClassName);
114: }
115: }
116:
117: private void addParameters(MutableEmbeddedComponentModel embedded,
118: String[] parameters) {
119: for (String parameter : parameters) {
120: KeyValue kv = TapestryInternalUtils
121: .parseKeyValue(parameter);
122:
123: embedded.addParameter(kv.getKey(), kv.getValue());
124: }
125: }
126:
127: }
|