001: /*
002: * Licensed to the Apache Software Foundation (ASF) under one or more
003: * contributor license agreements. See the NOTICE file distributed with
004: * this work for additional information regarding copyright ownership.
005: * The ASF licenses this file to You under the Apache License, Version 2.0
006: * (the "License"); you may not use this file except in compliance with
007: * the License. You may obtain a copy of the License at
008: *
009: * http://www.apache.org/licenses/LICENSE-2.0
010: *
011: * Unless required by applicable law or agreed to in writing, software
012: * distributed under the License is distributed on an "AS IS" BASIS,
013: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014: * See the License for the specific language governing permissions and
015: * limitations under the License.
016: *
017: * $Header:$
018: */
019: package org.apache.beehive.netui.compiler.genmodel;
020:
021: import org.apache.beehive.netui.compiler.CompilerUtils;
022: import org.apache.beehive.netui.compiler.JpfLanguageConstants;
023: import org.apache.beehive.netui.compiler.model.ActionModel;
024: import org.apache.beehive.netui.compiler.model.ForwardModel;
025: import org.apache.beehive.netui.compiler.model.FormBeanModel;
026: import org.apache.beehive.netui.compiler.typesystem.declaration.AnnotationInstance;
027: import org.apache.beehive.netui.compiler.typesystem.declaration.ClassDeclaration;
028: import org.apache.beehive.netui.compiler.typesystem.declaration.Declaration;
029: import org.apache.beehive.netui.compiler.typesystem.declaration.MethodDeclaration;
030: import org.apache.beehive.netui.compiler.typesystem.declaration.ParameterDeclaration;
031: import org.apache.beehive.netui.compiler.typesystem.declaration.TypeDeclaration;
032: import org.apache.beehive.netui.compiler.typesystem.type.DeclaredType;
033: import org.apache.beehive.netui.compiler.typesystem.type.TypeInstance;
034:
035: import java.util.HashSet;
036: import java.util.Iterator;
037: import java.util.List;
038:
039: public class GenActionModel extends ActionModel implements
040: JpfLanguageConstants {
041: public GenActionModel(Declaration sourceElement,
042: GenStrutsApp parentApp, ClassDeclaration jclass) {
043: super (parentApp);
044:
045: init(getActionName(sourceElement),
046: getActionAnnotation(sourceElement), parentApp, jclass);
047:
048: // Get the form class from the method argument.
049: setFormBeanName(getFormBean(sourceElement, parentApp));
050: }
051:
052: protected GenActionModel(String actionName, AnnotationInstance ann,
053: GenStrutsApp parentApp, ClassDeclaration jclass) {
054: super (parentApp);
055: init(actionName, ann, parentApp, jclass);
056: }
057:
058: protected void init(String actionName,
059: AnnotationInstance annotation, GenStrutsApp parentApp,
060: ClassDeclaration jclass) {
061: setActionName(actionName);
062:
063: //
064: // loginRequired
065: //
066: Boolean loginRequired = CompilerUtils.getBoolean(annotation,
067: LOGIN_REQUIRED_ATTR, true);
068: if (loginRequired == null) {
069: loginRequired = parentApp.getFlowControllerInfo()
070: .getMergedControllerAnnotation().isLoginRequired();
071: }
072: setLoginRequired(loginRequired);
073:
074: //
075: // prevent-double-submit
076: //
077: Boolean preventDoubleSubmit = CompilerUtils.getBoolean(
078: annotation, PREVENT_DOUBLE_SUBMIT_ATTR, false);
079: setPreventDoubleSubmit(preventDoubleSubmit.booleanValue());
080:
081: //
082: // readOnly
083: //
084: Boolean readOnly = CompilerUtils.getBoolean(annotation,
085: READONLY_ATTR, true);
086: if (readOnly == null) {
087: readOnly = parentApp.getFlowControllerInfo()
088: .getMergedControllerAnnotation().isReadOnly();
089: }
090: setReadonly(readOnly);
091:
092: //
093: // rolesAllowed -- avoid setting this if loginRequired is explicitly false.
094: //
095: if (loginRequired == null || loginRequired.booleanValue())
096: setRolesAllowed(annotation, jclass, parentApp);
097:
098: //
099: // type (delegating Action class, with the FlowController as parameter)
100: //
101: setType(FLOW_CONTROLLER_ACTION_CLASS);
102: setParameter(jclass.getQualifiedName());
103:
104: //
105: // form bean member -- the page-flow-scoped form referenced by the action (a member variable)
106: //
107: setFormMember(CompilerUtils.getString(annotation,
108: USE_FORM_BEAN_ATTR, true));
109:
110: //
111: // forwards
112: //
113: getForwards(annotation, jclass, parentApp);
114:
115: //
116: // validationErrorForward -- the forward used when validation fails
117: //
118: AnnotationInstance validateErrFwd = CompilerUtils
119: .getAnnotation(annotation,
120: VALIDATION_ERROR_FORWARD_ATTR, true);
121: boolean doValidation = false;
122: if (validateErrFwd != null) {
123: ForwardModel fwd = new GenForwardModel(parentApp,
124: validateErrFwd, jclass, " (validationErrorForward)");
125: addForward(fwd);
126: setInput(fwd.getName());
127: doValidation = true;
128: }
129:
130: //
131: // validate
132: //
133: Boolean explicitDoValidation = CompilerUtils.getBoolean(
134: annotation, DO_VALIDATION_ATTR, true);
135: setValidate(explicitDoValidation != null ? explicitDoValidation
136: .booleanValue() : doValidation);
137:
138: //
139: // exception-catches
140: //
141: List catches = CompilerUtils.getAnnotationArray(annotation,
142: CATCHES_ATTR, true);
143: GenExceptionModel.addCatches(catches, this , jclass, parentApp,
144: this );
145: }
146:
147: protected void setRolesAllowed(AnnotationInstance annotation,
148: ClassDeclaration jclass, GenStrutsApp parentApp) {
149: List rolesAllowed = CompilerUtils.getStringArray(annotation,
150: ROLES_ALLOWED_ATTR, true);
151: List classLevelRA = parentApp.getFlowControllerInfo()
152: .getMergedControllerAnnotation().getRolesAllowed();
153: Iterator it = null;
154:
155: if (rolesAllowed != null && classLevelRA != null) {
156: HashSet merged = new HashSet();
157: for (Iterator ii = rolesAllowed.iterator(); ii.hasNext();) {
158: String role = (String) ii.next();
159: merged.add(role);
160: }
161: for (Iterator ii = classLevelRA.iterator(); ii.hasNext();) {
162: String classLevelRole = (String) ii.next();
163: merged.add(classLevelRole);
164: }
165: it = merged.iterator();
166: } else if (rolesAllowed != null) {
167: it = rolesAllowed.iterator();
168: } else if (classLevelRA != null) {
169: it = classLevelRA.iterator();
170: }
171:
172: if (it != null && it.hasNext()) {
173: StringBuffer rolesAllowedStr = new StringBuffer((String) it
174: .next());
175:
176: while (it.hasNext()) {
177: rolesAllowedStr.append(',').append(
178: ((String) it.next()).trim());
179: }
180:
181: setRoles(rolesAllowedStr.toString());
182: }
183: }
184:
185: protected static String getActionName(Declaration sourceElement) {
186: return sourceElement.getSimpleName();
187: }
188:
189: /**
190: * @return the Struts name of the form bean.
191: */
192: protected String getFormBean(Declaration sourceElement,
193: GenStrutsApp parentApp) {
194: assert sourceElement instanceof MethodDeclaration : sourceElement
195: .getClass().getName();
196: ParameterDeclaration[] params = ((MethodDeclaration) sourceElement)
197: .getParameters();
198: String formBeanName = null;
199:
200: if (params.length > 0) {
201: assert params.length == 1 : params.length; // checker should catch this
202: TypeInstance paramType = CompilerUtils
203: .getGenericBoundsType(params[0].getType());
204: formBeanName = addFormBean(paramType, parentApp);
205: }
206:
207: return formBeanName;
208: }
209:
210: protected String addFormBean(TypeInstance paramType,
211: GenStrutsApp parentApp) {
212: paramType = CompilerUtils.getGenericBoundsType(paramType);
213: assert paramType instanceof DeclaredType : paramType.getClass()
214: .getName(); // checker should enforce this
215: TypeDeclaration decl = CompilerUtils
216: .getDeclaration((DeclaredType) paramType);
217: List formBeans = parentApp.getMatchingFormBeans(decl, Boolean
218: .valueOf(getFormMember() != null));
219: assert formBeans.size() > 0;
220: FormBeanModel formBeanModel = (FormBeanModel) formBeans.get(0);
221: setFormBeanMessageResourcesKey(formBeanModel
222: .getFormBeanMessageResourcesKey());
223:
224: //
225: // If this isn't an ActionForm-derived argument, keep track of the classname for the runtime.
226: //
227: if (!CompilerUtils.isAssignableFrom(PAGEFLOW_FORM_CLASS_NAME,
228: decl, parentApp.getEnv())) {
229: setFormClass(CompilerUtils.getLoadableName(decl));
230: }
231:
232: return formBeanModel.getName();
233: }
234:
235: protected AnnotationInstance getActionAnnotation(
236: Declaration sourceElement) {
237: assert sourceElement instanceof MethodDeclaration : sourceElement
238: .getClass().getName();
239: return CompilerUtils.getAnnotation(sourceElement,
240: ACTION_TAG_NAME);
241: }
242:
243: protected void getForwards(AnnotationInstance annotation,
244: ClassDeclaration jclass, GenStrutsApp parentApp) {
245: GenForwardModel.addForwards(annotation, this, jclass,
246: parentApp, null);
247: }
248: }
|