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.grammar;
020:
021: import org.apache.beehive.netui.compiler.AnnotationMemberType;
022: import org.apache.beehive.netui.compiler.CompilerUtils;
023: import org.apache.beehive.netui.compiler.Diagnostics;
024: import org.apache.beehive.netui.compiler.FlowControllerInfo;
025: import org.apache.beehive.netui.compiler.RuntimeVersionChecker;
026: import org.apache.beehive.netui.compiler.FatalCompileTimeException;
027: import org.apache.beehive.netui.compiler.typesystem.declaration.AnnotationInstance;
028: import org.apache.beehive.netui.compiler.typesystem.declaration.AnnotationTypeElementDeclaration;
029: import org.apache.beehive.netui.compiler.typesystem.declaration.AnnotationValue;
030: import org.apache.beehive.netui.compiler.typesystem.declaration.MemberDeclaration;
031: import org.apache.beehive.netui.compiler.typesystem.declaration.TypeDeclaration;
032: import org.apache.beehive.netui.compiler.typesystem.env.CoreAnnotationProcessorEnv;
033: import org.apache.beehive.netui.compiler.typesystem.type.TypeInstance;
034:
035: import java.util.Collection;
036: import java.util.Iterator;
037:
038: public class SimpleActionGrammar extends ActionGrammar {
039: private static String[][] REQUIRED_ATTRS = {
040: { NAME_ATTR },
041: { PATH_ATTR, TILES_DEFINITION_ATTR, RETURN_ACTION_ATTR,
042: NAVIGATE_TO_ATTR, FORWARD_REF_ATTR, ACTION_ATTR } };
043:
044: private static String[][] MUTUALLY_EXCLUSIVE_ATTRS = { {
045: USE_FORM_BEAN_ATTR, USE_FORM_BEAN_TYPE_ATTR } };
046:
047: private ForwardGrammar _forwardGrammar;
048:
049: public SimpleActionGrammar(CoreAnnotationProcessorEnv env,
050: Diagnostics diags, RuntimeVersionChecker rvc,
051: FlowControllerInfo fcInfo) {
052: super (env, diags, rvc, fcInfo);
053:
054: addMemberType(FORWARD_REF_ATTR, new ForwardRefType());
055: addMemberArrayGrammar(CONDITIONAL_FORWARDS_ATTR,
056: new SimpleActionForwardGrammar(env, diags, null, rvc,
057: fcInfo));
058:
059: //
060: // The rest of the attributes are checked by ForwardGrammar.
061: //
062: _forwardGrammar = new SimpleActionGrammarPart2();
063: }
064:
065: public String[][] getMutuallyExclusiveAttrs() {
066: return MUTUALLY_EXCLUSIVE_ATTRS;
067: }
068:
069: protected boolean onBeginCheck(AnnotationInstance annotation,
070: AnnotationInstance[] parentAnnotations,
071: MemberDeclaration classMember)
072: throws FatalCompileTimeException {
073: String name = CompilerUtils.getString(annotation, NAME_ATTR,
074: false);
075:
076: TypeDeclaration outerClass = CompilerUtils
077: .getOuterClass(classMember);
078: if (WebappPathOrActionType.actionExists(name, outerClass,
079: annotation, getEnv(), getFlowControllerInfo(), false)) {
080: if (!UniqueValueType.alreadyAddedErrorForValue(classMember,
081: annotation, name, getEnv())) {
082: addError(annotation, "error.duplicate-action",
083: new Object[] { name });
084: }
085: }
086:
087: //
088: // A simple action is really like a combination of an action and a forward. We extend ActionGrammar and
089: // then delegate to a ForwardGrammar here.
090: //
091: _forwardGrammar.check(annotation, parentAnnotations,
092: classMember);
093:
094: return super .onBeginCheck(annotation, parentAnnotations,
095: classMember);
096: }
097:
098: protected String getActionName(AnnotationInstance annotation,
099: MemberDeclaration classMember) {
100: return CompilerUtils.getString(annotation, NAME_ATTR, false);
101: }
102:
103: protected TypeInstance getFormBeanType(
104: AnnotationInstance annotation, MemberDeclaration classMember) {
105: // for a SimpleAction, the form bean type is wholly defined by the useFormBean attribute.
106: return getUseFormBeanType(annotation, classMember);
107: }
108:
109: private static class SimpleActionForwardGrammar extends
110: ForwardGrammar {
111: private static String[][] REQUIRED_SIMPLEACTION_ATTRS = {
112: { CONDITION_ATTR },
113: { PATH_ATTR, TILES_DEFINITION_ATTR, RETURN_ACTION_ATTR,
114: NAVIGATE_TO_ATTR, ACTION_ATTR } };
115:
116: public SimpleActionForwardGrammar(
117: CoreAnnotationProcessorEnv env, Diagnostics diags,
118: String requiredRuntimeVersion,
119: RuntimeVersionChecker runtimeVersionChecker,
120: FlowControllerInfo fcInfo) {
121: super (env, diags, requiredRuntimeVersion,
122: runtimeVersionChecker, fcInfo);
123: }
124:
125: public String[][] getRequiredAttrs() {
126: return REQUIRED_SIMPLEACTION_ATTRS;
127: }
128:
129: protected AnnotationMemberType getNameType() {
130: return new SimpleActionForwardNameType();
131: }
132:
133: private class SimpleActionForwardNameType extends
134: ForwardNameType {
135: public SimpleActionForwardNameType() {
136: super (CONDITIONAL_FORWARDS_ATTR);
137: }
138: }
139: }
140:
141: private class ForwardRefType extends AnnotationMemberType {
142: public ForwardRefType() {
143: super (null, SimpleActionGrammar.this );
144: }
145:
146: public Object onCheck(
147: AnnotationTypeElementDeclaration valueDecl,
148: AnnotationValue member,
149: AnnotationInstance[] parentAnnotations,
150: MemberDeclaration classMember, int annotationArrayIndex) {
151: Collection forwards = getFlowControllerInfo()
152: .getMergedControllerAnnotation().getForwards();
153: String forwardName = (String) member.getValue();
154:
155: for (Iterator ii = forwards.iterator(); ii.hasNext();) {
156: AnnotationInstance forwardAnn = (AnnotationInstance) ii
157: .next();
158: if (forwardName.equals(CompilerUtils.getString(
159: forwardAnn, NAME_ATTR, true)))
160: return null;
161: }
162:
163: // TODO: comment
164: if (forwardName.equals("_auto"))
165: return null;
166:
167: addError(member, "error.unresolvable-global-forward",
168: forwardName);
169: return null;
170: }
171: }
172:
173: private class SimpleActionGrammarPart2 extends ForwardGrammar {
174: public SimpleActionGrammarPart2() {
175: super (
176: SimpleActionGrammar.this .getEnv(),
177: SimpleActionGrammar.this .getDiagnostics(),
178: null,
179: SimpleActionGrammar.this .getRuntimeVersionChecker(),
180: SimpleActionGrammar.this .getFlowControllerInfo());
181: }
182:
183: protected AnnotationMemberType getNameType() {
184: // We don't want to use the normal name type, which checks for duplicate names among *forwards*.
185: return new AnnotationMemberType(null,
186: SimpleActionGrammar.this );
187: }
188:
189: public String[][] getRequiredAttrs() {
190: return REQUIRED_ATTRS;
191: }
192: }
193: }
|