de.intarsys.tools.functor.DeclaredArgs Maven / Gradle / Ivy
Show all versions of isrt Show documentation
/*
* Copyright (c) 2007, intarsys consulting GmbH
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* - Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* - Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* - Neither the name of intarsys nor the names of its contributors may be used
* to endorse or promote products derived from this software without specific
* prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
package de.intarsys.tools.functor;
import java.util.Set;
/**
* This {@link IArgs} implementation allows the declaration of arguments.
*
* The declaration is matched against the actual arguments defined in
* args
. The declaration defines a mapping from indexed to named
* and AND vice versa.
*
* If we have indexed args, a declaration associates a name with the argument in
* the sequence of declaration.
*
* If we have named args, a declaration defines the index of the argument with
* the same name.
*
*/
public class DeclaredArgs implements IArgs {
public static DeclaredArgs createStrict(IArgs args) {
DeclaredArgs result = new DeclaredArgs(args);
result.setLazy(false);
result.setStrict(true);
return result;
}
public static DeclaredArgs createStrictIfDeclared(IArgs args) {
DeclaredArgs result = new DeclaredArgs(args);
result.setLazy(true);
result.setStrict(true);
return result;
}
public static DeclaredArgs createTransparent(IArgs args) {
DeclaredArgs result = new DeclaredArgs(args);
result.setLazy(false);
result.setStrict(false);
return result;
}
private IArgs argsIn;
private IArgs argsOut;
private Args declaredArgs;
private boolean lazy = true;
private boolean strict = false;
protected DeclaredArgs(IArgs args) {
this.argsIn = args;
this.argsOut = args;
}
public void add(Object object) {
switchArgs();
declaredArgs.add(object);
}
public void clear() {
switchArgs();
declaredArgs.clear();
}
protected void declare(IFunctorCall call, ArgumentDeclaration argDecl)
throws DeclarationException {
declare(call, argDecl.getName(), argDecl.getIndex(), argDecl
.getDefaultFunctor());
}
protected void declare(IFunctorCall call, String name, int index,
IFunctor defaultFunctor) throws DeclarationException {
switchArgs();
Object value = null;
if (argsIn.isNamed()) {
value = argsIn.get(name);
if (value == null && argsIn.isDefined(name)) {
// avoid overwriting a client defined null value
return;
}
} else if (argsIn.isIndexed()) {
value = argsIn.get(index);
if (value == null && argsIn.isDefined(index)) {
return;
}
}
if (value instanceof IArgs || value == null) {
// if our value is undefined we compute and assign the result of the
// default functor
//
// if our value is an argument list itself, we must check for nested
// declarations
//
Object defaultValue = null;
if (defaultFunctor != null) {
try {
defaultValue = defaultFunctor.perform(call);
} catch (FunctorInvocationException e) {
throw new DeclarationException(e);
}
}
if (defaultValue instanceof IDeclaration[]) {
if (value == null) {
value = Args.create();
}
DeclaredArgs childDeclaredArgs = new DeclaredArgs((IArgs) value);
childDeclaredArgs.setLazy(isLazy());
childDeclaredArgs.setStrict(isStrict());
IDeclaration[] declarations = (IDeclaration[]) defaultValue;
for (int i = 0; i < declarations.length; i++) {
IDeclaration declaration = declarations[i];
if (!(declaration instanceof ArgumentDeclaration)) {
throw new DeclarationException(
"ArgumentDeclaration expected");
}
ArgumentDeclaration argDecl = (ArgumentDeclaration) declaration;
childDeclaredArgs.declare(call, argDecl);
}
value = childDeclaredArgs;
} else {
if (value == null) {
value = defaultValue;
}
}
}
declaredArgs.put(index, value);
declaredArgs.put(name, value);
}
public Object get(int pIndex) {
return argsOut.get(pIndex);
}
public Object get(int pIndex, Object defaultValue) {
return argsOut.get(pIndex, defaultValue);
}
public Object get(String name) {
return argsOut.get(name);
}
public Object get(String name, Object defaultValue) {
return argsOut.get(name, defaultValue);
}
public IArgs getArgsIn() {
return argsIn;
}
public boolean isDefined(int index) {
return argsOut.isDefined(index);
}
public boolean isDefined(String name) {
return argsOut.isDefined(name);
}
public boolean isIndexed() {
return true;
}
protected boolean isLazy() {
return lazy;
}
public boolean isNamed() {
return true;
}
protected boolean isStrict() {
return strict;
}
public Set names() {
return argsOut.names();
}
public void put(int index, Object value) {
switchArgs();
declaredArgs.put(index, value);
}
public void put(String name, Object value) {
switchArgs();
declaredArgs.put(name, value);
}
protected void setLazy(boolean lazy) {
this.lazy = lazy;
}
protected void setStrict(boolean strict) {
this.strict = strict;
if (strict && !lazy) {
switchArgs();
}
}
public int size() {
return argsOut.size();
}
protected void switchArgs() {
if (argsIn != argsOut) {
return;
}
declaredArgs = new Args();
if (strict) {
argsOut = declaredArgs;
} else {
argsOut = new ChainedArgs(declaredArgs, argsIn);
}
}
@Override
public String toString() {
return ArgTools.toString(this, "");
}
}