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: package org.apache.cocoon.forms.formmodel;
018:
019: import java.util.Iterator;
020: import java.util.List;
021: import java.util.ListIterator;
022:
023: import org.apache.cocoon.forms.FormsException;
024:
025: // TODO: The exception messages should use I18n.
026: /**
027: * This is the "{@link WidgetDefinition}" which is used to instantiate a
028: * {@link ClassDefinition}. The resolve step replaces this definition with
029: * the definitions contained in the referenced {@link ClassDefinition}.
030: *
031: * @version $Id: NewDefinition.java 449149 2006-09-23 03:58:05Z crossley $
032: */
033: public class NewDefinition extends AbstractWidgetDefinition {
034:
035: private boolean resolving;
036:
037: public NewDefinition() {
038: super ();
039: }
040:
041: private ClassDefinition getClassDefinition() throws Exception {
042: FormDefinition formDefinition = getFormDefinition();
043: WidgetDefinition classDefinition = null;
044:
045: // we found a form definition to ask
046: if (formDefinition != null) {
047: classDefinition = formDefinition
048: .getWidgetDefinition(getId());
049:
050: if (classDefinition == null) { // not found in local form, try library
051: classDefinition = formDefinition.getLocalLibrary()
052: .getDefinition(getId());
053: }
054: }
055:
056: if (classDefinition == null && getEnclosingLibrary() != null) { // not found in form's library, so ask enclosing library
057: classDefinition = getEnclosingLibrary().getDefinition(
058: getId());
059: }
060:
061: if (classDefinition == null) {
062: throw new FormsException("NewDefinition: Class with id '"
063: + getId() + "' does not exist.", getLocation());
064: }
065:
066: if (!(classDefinition instanceof ClassDefinition)) {
067: throw new FormsException("NewDefinition: Id '" + getId()
068: + "' is not a class.", getLocation());
069: }
070:
071: return (ClassDefinition) classDefinition;
072: }
073:
074: // TODO: Should add checking for union defaults which would cause non-terminating recursion.
075: public void resolve(List parents, WidgetDefinition parent)
076: throws Exception {
077: // Non-terminating recursion detection
078: if (resolving) {
079: // Search up parent list in hopes of finding a "Union" before finding previous "New" for this "Class".
080: ListIterator parentsIt = parents.listIterator(parents
081: .size());
082: while (parentsIt.hasPrevious()) {
083: WidgetDefinition definition = (WidgetDefinition) parentsIt
084: .previous();
085: if (definition instanceof UnionDefinition) {
086: break;
087: }
088:
089: if (definition == this ) {
090: throw new FormsException(
091: "NewDefinition: Non-terminating recursion detected in widget definition '"
092: + parent.getId() + "'.",
093: getLocation());
094: }
095: }
096: }
097:
098: // Resolution
099: resolving = true;
100: parents.add(this );
101: Iterator definitionsIt = getClassDefinition()
102: .getWidgetDefinitions().iterator();
103: parents.add(this );
104: while (definitionsIt.hasNext()) {
105: WidgetDefinition definition = (WidgetDefinition) definitionsIt
106: .next();
107: // Recursively resolve containers
108: if (definition instanceof ContainerDefinition) {
109: ((ContainerDefinition) definition).resolve(parents,
110: parent);
111: }
112:
113: // Add the current definition if it's not itself a "fd:new"
114: if (definition instanceof NewDefinition) {
115: ((NewDefinition) definition).resolve(parents, parent);
116: } else {
117: ((ContainerDefinition) parent)
118: .addWidgetDefinition(definition);
119: }
120: }
121: parents.remove(parents.size() - 1);
122: resolving = false;
123: }
124:
125: public Widget createInstance() {
126: return null;
127: }
128: }
|