/******************************************************************************* * Copyright (c) 2006 Sybase, Inc. and others. * * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * Sybase, Inc. - initial API and implementation *******************************************************************************/ package org.eclipse.jst.pagedesigner.validation.caret; import java.util.ArrayList; import java.util.Collections; import java.util.List; import org.eclipse.gef.EditPart; import org.eclipse.jst.pagedesigner.dom.DOMPositionHelper; import org.eclipse.jst.pagedesigner.dom.EditHelper; import org.eclipse.jst.pagedesigner.dom.EditModelQuery; import org.eclipse.jst.pagedesigner.dom.IDOMPosition; import org.eclipse.jst.pagedesigner.parts.DocumentEditPart; import org.eclipse.jst.pagedesigner.viewer.DesignPosition; import org.w3c.dom.Document; import org.w3c.dom.Node; /** * @author mengbo */ /*package*/ class DefaultPositionValidator implements IPositionMediator { private List _rules = new ArrayList(); /** * the validator's action data */ protected final ActionData _actionData; /** * @return Returns the _actionData. */ public ActionData getActionData() { return _actionData; } /** * @param actionData */ protected DefaultPositionValidator(ActionData actionData) { _actionData = actionData; initRules(); } /** * initialize the default rules */ protected void initRules() { _rules.clear(); addRule(new BasicPositionRule(this, _actionData)); addRule(new IETablePositionRule(_actionData)); addRule(new RootContainerPositionRule(_actionData)); addRule(new JSFRootContainerPositionRule(_actionData)); addRule(new WhitespacePositionMoveRule(_actionData)); } /** * @return Returns the _rules. */ public List getRules() { return Collections.unmodifiableList(_rules); } /** * @param rule */ protected void addRule(IValidationRule rule) { _rules.add(rule); } /* * (non-Javadoc) * * @see org.eclipse.jst.pagedesigner.caret.IValidator#hasEditableArea(org.w3c.dom.Node) */ public boolean hasEditableArea(Target target) { boolean result = true; List rules = getRules(); for (int i = 0, n = rules.size(); i < n; i++) { Object rule = rules.get(i); if (rule instanceof IPositionRule) { result &= ((IPositionRule) rule).hasEditableArea(target); } if (!result) { break; } } return result; } /* * (non-Javadoc) * * @see org.eclipse.jst.pagedesigner.caret.IValidator#isEditable(org.w3c.dom.Node) */ public boolean isEditable(Target target) { Node node = target.getNode(); boolean result = true; List rules = getRules(); for (int i = 0, n = rules.size(); i < n; i++) { Object rule = rules.get(i); if (rule instanceof IPositionRule) { result &= ((IPositionRule) rule).isEditable(new Target(node)); } if (!result) { break; } } return result; } /* * (non-Javadoc) * * @see org.eclipse.jst.pagedesigner.caret.IValidator#isValidPosition(org.eclipse.jst.pagedesigner.viewer.DesignPosition) */ public boolean isValidPosition(DesignPosition position) { return isValidPosition(DOMPositionHelper.toDOMPosition(position)); } /* * (non-Javadoc) * * @see org.eclipse.jst.pagedesigner.caret.IValidator#isValidPosition(org.eclipse.jst.pagedesigner.dom.IDOMPosition) */ public boolean isValidPosition(IDOMPosition position) { // if position is really a IDOMRefPosition, convert it to DOMPosition position = EditHelper.ensureDOMPosition(position); boolean refLeft = true, refRight = true, result = true; if (position == null) { return false; } List rules = getRules(); for (int i = 0, n = rules.size(); i < n; i++) { Object rule = rules.get(i); // rule may be an IValidationRule that is not a position rule // so only use those that are actually position rules if (rule instanceof IPositionRule) { // the IDOMPosition represents a position somewhere in a parent // node based on a node list index. We need to verify that the // parent is editable. result &= ((IPositionRule) rule).isEditable(new Target(position .getContainerNode())); if (result) { if (!position.isText()) { // TODO C.B: no sure what the point is here. It appears // as though it is validating whether the sibling either // side of this position is a valid location for this // action // ref1? Node node = EditModelQuery.getInstance().getSibling( position, true); if (node != null & refLeft) { refLeft &= ((IPositionRule) rule).canReference( new Target(node), false); } // ref2? node = EditModelQuery.getInstance().getSibling( position, false); if (node != null & refRight) { refRight = ((IPositionRule) rule).canReference( new Target(node), true); } if (!(refLeft | refRight)) { result = false; break; } } } else { break; } // } } } return (result & (refLeft | refRight)); } /** * Adjust the position to an editable area. */ public EditPart getEditableContainer(Target target) { EditPart part = target.getPart(); if (hasEditableArea(target)) { return target.getPart(); } while (part != null && !(part instanceof DocumentEditPart)) { if (hasEditableArea(target)) { break; } part = part.getParent(); target = new Target(part); } if (part instanceof DocumentEditPart && RootContainerPositionRule.hasBasicContainers((Document) part .getModel())) { Node node = RootContainerPositionRule .getBasicContainer((Document) part.getModel()); part = Target.resolvePart(node); } return part; } /* * (non-Javadoc) * * @see org.eclipse.jst.pagedesigner.caret.IValidator#canReference(org.w3c.dom.Node) */ public boolean canReference(Target target, boolean atRight) { boolean result = true; List rules = getRules(); for (int i = 0, n = rules.size(); i < n; i++) { Object rule = rules.get(i); if (rule instanceof IPositionRule) { result &= ((IPositionRule) rule).canReference(target, atRight); } if (!result) { break; } } return result; } }