01: // Copyright 2006 The Apache Software Foundation
02: //
03: // Licensed under the Apache License, Version 2.0 (the "License");
04: // you may not use this file except in compliance with the License.
05: // You may obtain a copy of the License at
06: //
07: // http://www.apache.org/licenses/LICENSE-2.0
08: //
09: // Unless required by applicable law or agreed to in writing, software
10: // distributed under the License is distributed on an "AS IS" BASIS,
11: // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12: // See the License for the specific language governing permissions and
13: // limitations under the License.
14:
15: package org.apache.tapestry.internal.services;
16:
17: import java.util.List;
18:
19: import org.apache.tapestry.annotations.InjectComponent;
20: import org.apache.tapestry.ioc.util.BodyBuilder;
21: import org.apache.tapestry.model.MutableComponentModel;
22: import org.apache.tapestry.runtime.Component;
23: import org.apache.tapestry.services.ClassTransformation;
24: import org.apache.tapestry.services.ComponentClassTransformWorker;
25: import org.apache.tapestry.services.TransformConstants;
26:
27: /**
28: * Identifies the {@link InjectComponent} annotation and adds code to initialize it to the core
29: * component.
30: */
31: public class InjectComponentWorker implements
32: ComponentClassTransformWorker {
33:
34: public void transform(ClassTransformation transformation,
35: MutableComponentModel model) {
36: List<String> names = transformation
37: .findFieldsWithAnnotation(InjectComponent.class);
38:
39: if (names.isEmpty())
40: return;
41:
42: // I can't imagine a scenario where a component would have more than one
43: // field with InjectComponent, but that's the way these APIs work, lists of names.
44:
45: BodyBuilder builder = new BodyBuilder();
46: builder.begin();
47:
48: builder.addln("%s core = %s.getCoreComponent();",
49: Component.class.getName(), transformation
50: .getResourcesFieldName());
51:
52: for (String fieldName : names) {
53: InjectComponent annotation = transformation
54: .getFieldAnnotation(fieldName,
55: InjectComponent.class);
56:
57: String fieldType = transformation.getFieldType(fieldName);
58:
59: builder.addln("try");
60: builder.begin();
61: builder.addln("%s = (%s) core;", fieldName, fieldType);
62: builder.end();
63: builder.addln("catch (ClassCastException ex)");
64: builder.begin();
65: builder
66: .addln(
67: "String message = %s.buildCastExceptionMessage(core, \"%s.%s\", \"%s\");",
68: InjectComponentWorker.class.getName(),
69: model.getComponentClassName(), fieldName,
70: fieldType);
71: builder.addln("throw new RuntimeException(message, ex);");
72: builder.end();
73:
74: transformation.makeReadOnly(fieldName);
75: transformation.claimField(fieldName, annotation);
76: }
77:
78: builder.end();
79:
80: transformation.extendMethod(
81: TransformConstants.CONTAINING_PAGE_DID_LOAD_SIGNATURE,
82: builder.toString());
83: }
84:
85: public static String buildCastExceptionMessage(Component component,
86: String fieldName, String fieldType) {
87: return ServicesMessages.componentNotAssignableToField(
88: component, fieldName, fieldType);
89: }
90: }
|