001    // Copyright 2005 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.enhance;
016    
017    import org.apache.hivemind.ApplicationRuntimeException;
018    import org.apache.hivemind.Location;
019    import org.apache.hivemind.service.BodyBuilder;
020    import org.apache.hivemind.service.MethodSignature;
021    import org.apache.tapestry.IPage;
022    import org.apache.tapestry.spec.InjectSpecification;
023    
024    import java.lang.reflect.Modifier;
025    
026    /**
027     * Injects code to access a named page within the application.
028     * 
029     * @author Howard Lewis Ship
030     * @since 4.0
031     */
032    public class InjectPageWorker implements InjectEnhancementWorker
033    {
034        public void performEnhancement(EnhancementOperation op, InjectSpecification spec)
035        {
036            performEnhancement(op, spec.getObject(), spec.getProperty(), spec.getLocation());
037        }
038    
039        public void performEnhancement(EnhancementOperation op, String pageName, String propertyName,
040                Location location)
041        {
042            Class propertyType = op.getPropertyType(propertyName);
043    
044            if (propertyType == null)
045                propertyType = Object.class;
046            else if (propertyType.isPrimitive())
047                throw new ApplicationRuntimeException(EnhanceMessages.wrongTypeForPageInjection(
048                        propertyName,
049                        propertyType), null, location, null);
050    
051            op.claimReadonlyProperty(propertyName);
052    
053            MethodSignature sig = new MethodSignature(propertyType, op
054                    .getAccessorMethodName(propertyName), null, null);
055    
056            BodyBuilder builder = new BodyBuilder();
057    
058            builder.add("return ");
059    
060            // If the property type is not IPage or a superclass of IPage then a cast
061            // is needed.
062    
063            if (!propertyType.isAssignableFrom(IPage.class))
064                builder.add("({0})", propertyType.getName());
065    
066            builder.add("getPage().getRequestCycle().getPage(\"{0}\");", pageName);
067    
068            op.addMethod(Modifier.PUBLIC, sig, builder.toString(), location);
069        }
070    }