| /******************************************************************************* |
| * 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.Arrays; |
| |
| import org.eclipse.jst.jsf.common.dom.TagIdentifier; |
| import org.eclipse.jst.jsf.core.internal.tld.ITLDConstants; |
| import org.eclipse.jst.pagedesigner.dom.EditModelQuery; |
| import org.w3c.dom.Document; |
| import org.w3c.dom.Node; |
| |
| /** |
| * Ensure the DnD of jsf component should be within f:view or f:subview. |
| * |
| * @author mengbo |
| */ |
| public class JSFRootContainerPositionRule extends DefaultPositionRule { |
| |
| private final static int DEFAULT_MAX_DEPTH_SEARCH = 3; |
| |
| /** |
| * TODO: this is not enough because it ignores the uri and keys on only |
| * the name of the tag. |
| */ |
| /*package*/ static final String[] JSF_ROOT_CONTAINERS = { "view", "subview" }; //$NON-NLS-1$ //$NON-NLS-2$ |
| |
| /** |
| * @param actionData |
| */ |
| public JSFRootContainerPositionRule(ActionData actionData) { |
| super(actionData); |
| } |
| |
| /* |
| * (non-Javadoc) |
| * |
| * @see org.eclipse.jst.pagedesigner.validation.caret.IPositionRule#hasEditableArea(org.eclipse.jst.pagedesigner.validation.caret.Target) |
| */ |
| public boolean hasEditableArea(Target target) { |
| Node node = target.getNode(); |
| if (hasBasicContainers(EditModelQuery.getDocumentNode(node),DEFAULT_MAX_DEPTH_SEARCH)) { |
| ActionData actionData = getActionData(); |
| if (actionData instanceof DropActionData) { |
| DropActionData dropActionData = (DropActionData) actionData; |
| TagIdentifier tagId = |
| (TagIdentifier) dropActionData.getDropData().getTagIdentifiers().get(0); |
| final String uri = tagId.getUri(); |
| if (ITLDConstants.URI_JSF_HTML.equalsIgnoreCase(uri) |
| || ITLDConstants.URI_JSF_CORE.equalsIgnoreCase(uri)) { |
| boolean result = EditModelQuery.isChild( |
| JSF_ROOT_CONTAINERS, node, true, false); |
| return result |
| || EditModelQuery.getChild(node, |
| JSF_ROOT_CONTAINERS, 3, false) != null; |
| } |
| } else if (getActionData().getActionType() == ActionData.DATABINDING_DND) { |
| boolean result = EditModelQuery.isChild(JSF_ROOT_CONTAINERS, |
| node, true, false); |
| return result |
| || EditModelQuery.getChild(node, JSF_ROOT_CONTAINERS, 3, |
| false) != null; |
| } |
| } |
| return super.isEditable(target); |
| } |
| |
| /* |
| * (non-Javadoc) |
| * |
| * @see org.eclipse.jst.pagedesigner.validation.caret.IPositionRule#isEditable(org.eclipse.jst.pagedesigner.validation.caret.Target) |
| */ |
| public boolean isEditable(Target target) { |
| boolean result = true; |
| Node node = target.getNode(); |
| if (hasBasicContainers(EditModelQuery.getDocumentNode(node), DEFAULT_MAX_DEPTH_SEARCH)) { |
| ActionData actionData = getActionData(); |
| if (actionData instanceof DropActionData) { |
| DropActionData dropActionData = (DropActionData) actionData; |
| TagIdentifier tagId = |
| (TagIdentifier) dropActionData.getDropData().getTagIdentifiers().get(0); |
| final String uri = tagId.getUri(); |
| |
| if (ITLDConstants.URI_JSF_HTML.equalsIgnoreCase(uri) |
| || ITLDConstants.URI_JSF_CORE.equalsIgnoreCase(uri)) { |
| result = EditModelQuery.isChild(JSF_ROOT_CONTAINERS, |
| node, true, false); |
| } |
| } else if (getActionData().getActionType() == ActionData.DATABINDING_DND) { |
| result = EditModelQuery.isChild(JSF_ROOT_CONTAINERS, node, |
| true, false); |
| } |
| return result; |
| } |
| return super.isEditable(target); |
| } |
| |
| |
| /** |
| * @param document |
| * @param maxDepth |
| * @return the closest tag called "view" or "subview" to the root of document |
| * search to a maximum tag depth of maxDepth |
| */ |
| public static Node getBasicContainer(Document document, int maxDepth) { |
| Node node = EditModelQuery.getChild(document, JSF_ROOT_CONTAINERS, maxDepth, |
| false); |
| return node; |
| } |
| |
| /** |
| * We need to see if body, view are there. and they should be at first or |
| * second level. |
| * |
| * @param document |
| * @param maxDepth |
| * @return true if document has a view and subview limited to a maximum search |
| * depth of maxDepth |
| */ |
| public static boolean hasBasicContainers(Document document, int maxDepth) { |
| return getBasicContainer(document, maxDepth) != null; |
| } |
| |
| /* |
| * (non-Javadoc) |
| * |
| * @see org.eclipse.jst.pagedesigner.validation.caret.IPositionRule#canReference(org.eclipse.jst.pagedesigner.validation.caret.Target, |
| * boolean) |
| */ |
| public boolean canReference(Target target, boolean atRight) { |
| Node node = target.getNode(); |
| if (node.getLocalName() != null) { |
| // if the local name of the target is in the list of JSF root |
| // containers |
| if (Arrays.asList(JSF_ROOT_CONTAINERS).contains( |
| node.getLocalName().toLowerCase())) { |
| |
| // verify that either the target is |
| return EditModelQuery.isChild( |
| RootContainerPositionRule.HTML_ROOT_CONTAINERS, node, |
| false, false) |
| || EditModelQuery.isChild(JSF_ROOT_CONTAINERS, node, |
| false, false); |
| } |
| } |
| return super.canReference(target, atRight); |
| } |
| } |