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.woody.formmodel;
018:
019: import java.util.Iterator;
020: import java.util.List;
021: import java.util.ListIterator;
022:
023: // TODO: The exception messages should use I18n.
024: /**
025: * This is the "{@link WidgetDefinition}" which is used to instantiate a
026: * {@link ClassDefinition}. The resolve step replaces this definition with
027: * the definitions contained in the referenced {@link ClassDefinition}.
028: *
029: * @author Timothy Larson
030: * @version $Id: NewDefinition.java 433543 2006-08-22 06:22:54Z crossley $
031: */
032: public class NewDefinition extends AbstractWidgetDefinition {
033: private boolean resolving;
034: private ClassDefinition classDefinition;
035:
036: public NewDefinition() {
037: super ();
038: resolving = false;
039: classDefinition = null;
040: }
041:
042: private ClassDefinition getClassDefinition() throws Exception {
043: FormDefinition formDefinition = getFormDefinition();
044: WidgetDefinition classDefinition = formDefinition
045: .getWidgetDefinition(getId());
046: if (classDefinition == null)
047: throw new Exception("NewDefinition: Class with id \""
048: + getId() + "\" does not exist (" + getLocation()
049: + ")");
050: if (!(classDefinition instanceof ClassDefinition))
051: throw new Exception("NewDefinition: Id \"" + getId()
052: + "\" is not a class (" + getLocation() + ")");
053: return (ClassDefinition) classDefinition;
054: }
055:
056: // TODO: Should add checking for union defaults which would cause non-terminating recursion.
057: public void resolve(List parents, WidgetDefinition parent)
058: throws Exception {
059: // Non-terminating recursion detection
060: if (resolving) {
061: // Search up parent list in hopes of finding a "Union" before finding previous "New" for this "Class".
062: ListIterator parentsIt = parents.listIterator(parents
063: .size());
064: while (parentsIt.hasPrevious()) {
065: WidgetDefinition definition = (WidgetDefinition) parentsIt
066: .previous();
067: if (definition instanceof UnionDefinition)
068: break;
069: if (definition == this )
070: throw new Exception(
071: "NewDefinition: Non-terminating recursion detected in widget definition : "
072: + parent.getId() + " ("
073: + getLocation() + ")");
074: }
075: }
076: // Resolution
077: resolving = true;
078: parents.add(this );
079: classDefinition = getClassDefinition();
080: Iterator definitionsIt = classDefinition.getWidgetDefinitions()
081: .iterator();
082: parents.add(this );
083: while (definitionsIt.hasNext()) {
084: WidgetDefinition definition = (WidgetDefinition) definitionsIt
085: .next();
086: if (definition instanceof ContainerDefinition) {
087: ((ContainerDefinition) definition).resolve(parents,
088: parent);
089: }
090: if (!(definition instanceof NewDefinition)) {
091: ((ContainerDefinition) parent)
092: .addWidgetDefinition(definition);
093: }
094: }
095: parents.remove(parents.size() - 1);
096: resolving = false;
097: }
098:
099: public Widget createInstance() {
100: return null;
101: }
102: }
|