/* * The contents of this file are subject to the Mozilla Public License * Version 1.1 (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.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See * the License for the specific language governing rights and limitations * under the License. * * The Original Code is the Kowari Metadata Store. * * The Initial Developer of the Original Code is Plugged In Software Pty * Ltd (http://www.pisoftware.com, mailto:info@pisoftware.com). Portions * created by Plugged In Software Pty Ltd are Copyright (C) 2001,2002 * Plugged In Software Pty Ltd. All Rights Reserved. * * Contributor(s): * ConstraintLocalizations contributed by Netymon Pty Ltd on behalf of * The Australian Commonwealth Government under contract 4500507038. * getModel() contributed by Netymon Pty Ltd on behalf of * The Australian Commonwealth Government under contract 4500507038. * * [NOTE: The text of this Exhibit A may differ slightly from the text * of the notices in the Source Code files of the Original Code. You * should use the text of this Exhibit A rather than the text found in the * Original Code Source Code for Your Modifications.] * */ package org.mulgara.resolver; // Java 2 standard packages import java.util.*; // Third party packages import org.apache.log4j.Logger; // Local packages import org.mulgara.query.*; import org.mulgara.resolver.spi.ConstraintBindingHandler; import org.mulgara.resolver.spi.ConstraintLocalization; import org.mulgara.resolver.spi.ConstraintGraphRewrite; import org.mulgara.resolver.spi.ConstraintResolutionHandler; import org.mulgara.resolver.spi.ConstraintVariableRewrite; import org.mulgara.resolver.spi.GraphResolutionHandler; import org.mulgara.resolver.spi.QueryEvaluationContext; import org.mulgara.store.tuples.Tuples; import org.mulgara.util.NVPair; import org.mulgara.util.ThreadUtil; /** * Localized version of a global {@link Query}. * * As well as providing coordinate transformation from global to local * coordinates, this adds methods to partially resolve the query. * * @created 2004-05-06 * @author <a href="http://www.pisoftware.com/raboczi">Simon Raboczi</a> * @version $Revision: 1.13 $ * @modified $Date: 2005/05/15 04:12:15 $ * @maintenanceAuthor $Author: pgearon $ * @company <a href="mailto:info@PIsoftware.com">Plugged In Software</a> * @copyright ©2004 <a href="http://www.tucanatech.com/">Tucana * Technology, Inc</a> * @licence <a href="{@docRoot}/../../LICENCE">Mozilla Public License v1.1</a> */ public class ConstraintOperations { /** Logger. */ private static final Logger logger = Logger.getLogger(ConstraintOperations.class.getName()); static Map<Class<? extends ConstraintExpression>,Object> modelResolutionHandlers = new HashMap<Class<? extends ConstraintExpression>,Object>(); static Map<Class<? extends ConstraintExpression>,Object> constraintResolutionHandlers = new HashMap<Class<? extends ConstraintExpression>,Object>(); static Map<Class<? extends ConstraintExpression>,Object> constraintBindingHandlers = new HashMap<Class<? extends ConstraintExpression>,Object>(); static Map<Class<? extends ConstraintExpression>,Object> constraintLocalizations = new HashMap<Class<? extends ConstraintExpression>,Object>(); static Map<Class<? extends ConstraintExpression>,Object> constraintModelRewrites = new HashMap<Class<? extends ConstraintExpression>,Object>(); static Map<Class<? extends ConstraintExpression>,Object> constraintVariableRewrites = new HashMap<Class<? extends ConstraintExpression>,Object>(); static { DefaultConstraintHandlers.initializeHandlers(); } static void addConstraintResolutionHandlers(NVPair<Class<? extends ConstraintExpression>,Object>[] resolutionHandlers) throws RuntimeException { addToMap(resolutionHandlers, constraintResolutionHandlers, ConstraintExpression.class, ConstraintResolutionHandler.class); } static void addConstraintBindingHandlers(NVPair<Class<? extends ConstraintExpression>,Object>[] bindingHandlers) throws RuntimeException { addToMap(bindingHandlers, constraintBindingHandlers, ConstraintExpression.class, ConstraintBindingHandler.class); } static void addModelResolutionHandlers(NVPair<Class<? extends ConstraintExpression>,Object>[] resolutionHandlers) throws RuntimeException { addToMap(resolutionHandlers, modelResolutionHandlers, GraphExpression.class, GraphResolutionHandler.class); } static void addConstraintModelRewrites(NVPair<Class<? extends ConstraintExpression>,Object>[] resolutionHandlers) throws RuntimeException { addToMap(resolutionHandlers, constraintModelRewrites, ConstraintExpression.class, ConstraintGraphRewrite.class); } static void addConstraintVariableRewrites(NVPair<Class<? extends ConstraintExpression>,Object>[] resolutionHandlers) throws RuntimeException { addToMap(resolutionHandlers, constraintVariableRewrites, ConstraintExpression.class, ConstraintVariableRewrite.class); } static void addConstraintLocalizations(NVPair<Class<? extends ConstraintExpression>,Object>[] resolutionHandlers) throws RuntimeException { addToMap(resolutionHandlers, constraintLocalizations, Constraint.class, ConstraintLocalization.class); } static boolean constraintRegistered(Class<? extends ConstraintExpression> constraintClass) { return modelResolutionHandlers.containsKey(constraintClass) || constraintResolutionHandlers.containsKey(constraintClass) || constraintLocalizations.containsKey(constraintClass) || constraintModelRewrites.containsKey(constraintClass); } static void addToMap(NVPair<Class<? extends ConstraintExpression>,Object>[] pairs, Map<Class<? extends ConstraintExpression>,Object> dest, Class<?> keyClass, Class<?> valueClass) throws ClassCastException { // Type check array. for (int i = 0; i < pairs.length; i++) { Class<?> key = pairs[i].getName(); Object value = pairs[i].getValue(); if (!keyClass.isAssignableFrom(key)) { throw new ClassCastException(key + " is not assignable to " + keyClass); } if (!valueClass.isAssignableFrom(value.getClass())) { throw new ClassCastException(value.getClass() + " is not assignable to " + valueClass); } } // Insert array into map. for (int i = 0; i < pairs.length; i++) { dest.put(pairs[i].getName(), pairs[i].getValue()); } } public static Tuples resolveModelExpression(QueryEvaluationContext context, GraphExpression modelExpr, Constraint constraint) throws QueryException { try { ThreadUtil.checkForInterrupt(QueryException.class); if (logger.isDebugEnabled()) { logger.debug("Resolving " + constraint + " against GraphExpression[" + modelExpr.getClass() + "]"); } GraphResolutionHandler op = (GraphResolutionHandler)modelResolutionHandlers.get(modelExpr.getClass()); if (op == null) { throw new QueryException("Unknown GraphExpression type: " + modelExpr.getClass() + " known types: " + modelResolutionHandlers.keySet()); } Tuples result = op.resolve(context, modelExpr, constraint); if (logger.isDebugEnabled()) { logger.debug("Resolved " + constraint + " against GraphExpression[" + modelExpr.getClass() + "] to: " + result); } return result; } catch (QueryException eq) { throw eq; } catch (Exception e) { throw new QueryException("Resolving model expression failed", e); } } public static Tuples resolveConstraintExpression(QueryEvaluationContext context, GraphExpression modelExpr, ConstraintExpression constraintExpr) throws QueryException { try { ThreadUtil.checkForInterrupt(QueryException.class); if (logger.isDebugEnabled()) { logger.debug("Resolving ConstraintExpression[" + constraintExpr.getClass() + "]"); } ConstraintResolutionHandler op = (ConstraintResolutionHandler)constraintResolutionHandlers.get(constraintExpr.getClass()); if (op == null) { throw new QueryException("Unknown ConstraintExpression type: " + constraintExpr.getClass() + " known types: " + constraintResolutionHandlers.keySet()); } Tuples result = op.resolve(context, modelExpr, constraintExpr); if (logger.isDebugEnabled()) { logger.debug("Resolved ConstraintExpression[" + constraintExpr.getClass() + "] to: " + result); } return result; } catch (QueryException eq) { throw eq; } catch (Exception e) { throw new QueryException("Failed to resolve constraintExpression", e); } } public static ConstraintExpression bindVariables(Map<Variable,Value> bindings, ConstraintExpression constraintExpr) throws QueryException { try { if (logger.isDebugEnabled()) { logger.debug("Binding Variables in ConstraintExpression[" + constraintExpr.getClass() + "]"); logger.debug("binding variables for: " + constraintExpr + " with " + bindings); } ConstraintBindingHandler op = (ConstraintBindingHandler)constraintBindingHandlers.get(constraintExpr.getClass()); if (op == null) { throw new QueryException("Unknown ConstraintExpression type: " + constraintExpr.getClass() + " known types: " + constraintBindingHandlers.keySet()); } ConstraintExpression result = op.bindVariables(bindings, constraintExpr); if (logger.isDebugEnabled()) { logger.debug("Bound variables in ConstraintExpression[" + constraintExpr.getClass() + "] to: " + result); } return result; } catch (QueryException eq) { throw eq; } catch (Exception e) { throw new QueryException("Failed to bind variables in constraintExpression", e); } } public static Constraint localize(QueryEvaluationContext context, Constraint constraint) throws Exception { if (logger.isDebugEnabled()) { logger.debug("Localizing Constraint[" + constraint.getClass() + "]"); } ConstraintLocalization op = (ConstraintLocalization)constraintLocalizations.get(constraint.getClass()); if (op == null) { throw new QueryException("Unknown Constraint type: " + constraint.getClass() + " known types: " + constraintLocalizations.keySet()); } Constraint result = op.localize(context, constraint); if (logger.isDebugEnabled()) { logger.debug("Localized Constraint[" + constraint.getClass() + "] to: " + result); } return result; } public static Constraint rewriteConstraintModel(ConstraintElement newModel, Constraint constraint) throws QueryException { try { if (logger.isDebugEnabled()) { logger.debug("Rewriting Graph" + newModel + " in " + constraint); } ConstraintGraphRewrite op = (ConstraintGraphRewrite)constraintModelRewrites.get(constraint.getClass()); if (op == null) { throw new QueryException("Unknown Constraint type: " + constraint.getClass() + " known types: " + constraintModelRewrites.keySet()); } Constraint result = op.rewrite(newModel, constraint); if (logger.isDebugEnabled()) { logger.debug("Rewrote Graph " + newModel + " in " + constraint + " to " + result); } return result; } catch (QueryException eq) { throw eq; } catch (Exception e) { throw new QueryException("Rewriting constraint failed", e); } } public static Constraint rewriteConstraintVariable(Variable modelVar, Variable newVar, Constraint constraint) throws QueryException { try { if (logger.isDebugEnabled()) { logger.debug("Rewriting variable " + modelVar + " in " + constraint + " and setting graph"); } ConstraintVariableRewrite op = (ConstraintVariableRewrite)constraintVariableRewrites.get(constraint.getClass()); if (op == null) { throw new QueryException("Unknown Constraint type: " + constraint.getClass() + " known types: " + constraintVariableRewrites.keySet()); } Constraint result = op.rewrite(modelVar, newVar, constraint); if (logger.isDebugEnabled()) { logger.debug("Rewrote Graph " + modelVar + " in " + constraint + " to " + result); } return result; } catch (QueryException eq) { throw eq; } catch (Exception e) { throw new QueryException("Rewriting constraint failed", e); } } public static Constraint replace(Map<Variable,Value> bindings, Constraint constraint) throws QueryException { return ConstraintFactory.newConstraint(replace(bindings, constraint.getElement(0)), replace(bindings, constraint.getElement(1)), replace(bindings, constraint.getElement(2)), replace(bindings, constraint.getModel())); } public static ConstraintElement replace(Map<Variable,Value> bindings, ConstraintElement element) { if (element instanceof Variable && bindings.containsKey(element)) { return (ConstraintElement)bindings.get(element); } else { return element; } } public static List<ConstraintExpression> replaceOperationArgs(Map<Variable,Value> bindings, ConstraintOperation constraint) throws QueryException { List<ConstraintExpression> newArgs = new ArrayList<ConstraintExpression>(); for (ConstraintExpression expr: constraint.getElements()) { newArgs.add(bindVariables(bindings, expr)); } return newArgs; } }