blob: 18b38f188d412f8306e1666e3135ba083547afeb [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.cocoon.forms.formmodel;
import java.util.Iterator;
import java.util.List;
import java.util.ListIterator;
import org.apache.cocoon.forms.FormsException;
// TODO: The exception messages should use I18n.
/**
* This is the "{@link WidgetDefinition}" which is used to instantiate a
* {@link ClassDefinition}. The resolve step replaces this definition with
* the definitions contained in the referenced {@link ClassDefinition}.
*
* @version $Id$
*/
public class NewDefinition extends AbstractWidgetDefinition {
private boolean resolving;
public NewDefinition() {
super();
}
private ClassDefinition getClassDefinition() throws Exception {
FormDefinition formDefinition = getFormDefinition();
WidgetDefinition classDefinition = null;
// we found a form definition to ask
if (formDefinition != null) {
classDefinition = formDefinition.getWidgetDefinition(getId());
if (classDefinition == null) { // not found in local form, try library
classDefinition = formDefinition.getLocalLibrary().getDefinition(getId());
}
}
if (classDefinition == null && getEnclosingLibrary() != null) { // not found in form's library, so ask enclosing library
classDefinition = getEnclosingLibrary().getDefinition(getId());
}
if (classDefinition == null) {
throw new FormsException("NewDefinition: Class with id '" + getId() + "' does not exist.",
getLocation());
}
if (!(classDefinition instanceof ClassDefinition)) {
throw new FormsException("NewDefinition: Id '" + getId() + "' is not a class.",
getLocation());
}
return (ClassDefinition) classDefinition;
}
// TODO: Should add checking for union defaults which would cause non-terminating recursion.
public void resolve(List parents, WidgetDefinition parent) throws Exception {
// Non-terminating recursion detection
if (resolving) {
// Search up parent list in hopes of finding a "Union" before finding previous "New" for this "Class".
ListIterator parentsIt = parents.listIterator(parents.size());
while(parentsIt.hasPrevious()) {
WidgetDefinition definition = (WidgetDefinition)parentsIt.previous();
if (definition instanceof UnionDefinition) {
break;
}
if (definition == this) {
throw new FormsException("NewDefinition: Non-terminating recursion detected in widget definition '" + parent.getId() + "'.",
getLocation());
}
}
}
// Resolution
resolving = true;
parents.add(this);
Iterator definitionsIt = getClassDefinition().getWidgetDefinitions().iterator();
parents.add(this);
while (definitionsIt.hasNext()) {
WidgetDefinition definition = (WidgetDefinition) definitionsIt.next();
// Recursively resolve containers
if (definition instanceof ContainerDefinition) {
((ContainerDefinition) definition).resolve(parents, parent);
}
// Add the current definition if it's not itself a "fd:new"
if (definition instanceof NewDefinition) {
((NewDefinition) definition).resolve(parents, parent);
} else {
((ContainerDefinition) parent).addWidgetDefinition(definition);
}
}
parents.remove(parents.size() - 1);
resolving = false;
}
public Widget createInstance() {
return null;
}
}