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 java.lang.reflect.Modifier;
018: import java.util.List;
019:
020: import org.apache.tapestry.annotations.InjectPage;
021: import org.apache.tapestry.internal.structure.Page;
022: import org.apache.tapestry.ioc.internal.util.InternalUtils;
023: import org.apache.tapestry.ioc.util.BodyBuilder;
024: import org.apache.tapestry.model.MutableComponentModel;
025: import org.apache.tapestry.services.ClassTransformation;
026: import org.apache.tapestry.services.ComponentClassResolver;
027: import org.apache.tapestry.services.ComponentClassTransformWorker;
028: import org.apache.tapestry.services.MethodSignature;
029:
030: /**
031: * Peforms transformations that allow pages to be injected into components.
032: *
033: * @see InjectPage
034: */
035: public class InjectPageWorker implements ComponentClassTransformWorker {
036: private final RequestPageCache _requestPageCache;
037:
038: private final ComponentClassResolver _resolver;
039:
040: public InjectPageWorker(RequestPageCache requestPageCache,
041: ComponentClassResolver resolver) {
042: _requestPageCache = requestPageCache;
043: _resolver = resolver;
044: }
045:
046: public void transform(ClassTransformation transformation,
047: MutableComponentModel model) {
048: List<String> names = transformation
049: .findFieldsWithAnnotation(InjectPage.class);
050:
051: if (names.isEmpty())
052: return;
053:
054: String cacheFieldName = transformation.addInjectedField(
055: RequestPageCache.class, "_requestPageCache",
056: _requestPageCache);
057:
058: for (String name : names)
059: addInjectedPage(transformation, name, cacheFieldName);
060:
061: }
062:
063: private void addInjectedPage(ClassTransformation transformation,
064: String fieldName, String cacheFieldName) {
065: InjectPage annotation = transformation.getFieldAnnotation(
066: fieldName, InjectPage.class);
067:
068: String pageName = annotation.value();
069:
070: String fieldType = transformation.getFieldType(fieldName);
071: String methodName = transformation.newMemberName(
072: "read_inject_page", fieldName);
073:
074: String injectedPageName = InternalUtils.isBlank(pageName) ? _resolver
075: .resolvePageClassNameToPageName(fieldType)
076: : pageName;
077:
078: MethodSignature sig = new MethodSignature(Modifier.PRIVATE,
079: fieldType, methodName, null, null);
080:
081: BodyBuilder builder = new BodyBuilder();
082: builder.begin();
083:
084: builder.add("%s page = %s.get(\"%s\");", Page.class.getName(),
085: cacheFieldName, injectedPageName);
086:
087: builder.addln(
088: "return (%s) page.getRootElement().getComponent();",
089: fieldType);
090:
091: builder.end();
092:
093: transformation.addMethod(sig, builder.toString());
094: transformation.replaceReadAccess(fieldName, methodName);
095: transformation.makeReadOnly(fieldName);
096: transformation.removeField(fieldName);
097:
098: transformation.claimField(fieldName, annotation);
099: }
100: }
|