/******************************************************************************
* Copyright (c) 2010-2013, Linagora
*
* 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:
* Linagora - initial API and implementation
*******************************************************************************/
package com.ebmwebsourcing.petals.common.internal.provisional.sse;
import java.util.ArrayList;
import java.util.List;
import org.eclipse.wst.xml.core.internal.contentmodel.CMElementDeclaration;
import org.eclipse.wst.xml.core.internal.contentmodel.CMNode;
import org.eclipse.wst.xml.core.internal.contentmodel.modelquery.ModelQuery;
import org.eclipse.wst.xml.core.internal.contentmodel.modelquery.ModelQueryAction;
import org.eclipse.wst.xml.core.internal.modelquery.ModelQueryUtil;
import org.eclipse.wst.xml.ui.internal.contentassist.XMLContentAssistProcessor;
import org.eclipse.wst.xsd.contentmodel.internal.XSDImpl;
import org.eclipse.wst.xsd.contentmodel.internal.XSDImpl.XSDElementDeclarationAdapter;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import com.ebmwebsourcing.petals.common.internal.provisional.utils.DomUtils;
/**
* @author Vincent Zurczak - EBM WebSourcing
*
* FIXME: this class relies on non-API code.
* Changing the WTP version may result in troubles and not-working features.
*/
@SuppressWarnings( "restriction" )
public class PetalsContentAssistProcessor extends XMLContentAssistProcessor {
/**
* Overrides the super method so that it only proposes relevant candidates.
* <p>
* In particular, this implementation looks at the available name spaces
* to determine whether a candidate is a good one or not.
* </p>
*
* (non-Javadoc)
* @see org.eclipse.wst.xml.ui.internal.contentassist.AbstractContentAssistProcessor
* #getAvailableChildElementDeclarations(org.w3c.dom.Element, int, int)
*/
@SuppressWarnings( "rawtypes" )
@Override
protected List getAvailableChildElementDeclarations( Element parentElement, int childPosition, int kindOfAction ) {
List<Object> cmnodes = new ArrayList<Object> ();
Document doc = parentElement.getOwnerDocument();
ModelQuery mQuery = ModelQueryUtil.getModelQuery( doc );
CMElementDeclaration parentEd = mQuery.getCMElementDeclaration( parentElement );
if( parentEd != null ) {
List<?> modelQueryActions = new ArrayList<Object> ();
mQuery.getInsertActions(
parentElement,
parentEd,
childPosition,
ModelQuery.INCLUDE_CHILD_NODES | ModelQuery.INCLUDE_SEQUENCE_GROUPS,
ModelQuery.VALIDITY_NONE,
modelQueryActions );
boolean isBlockValid = mQuery.isContentValid( parentElement );
for( Object o : modelQueryActions ) {
ModelQueryAction action = (ModelQueryAction) o;
if( childPosition < 0 ||
action.getStartIndex() <= childPosition
&& childPosition <= action.getEndIndex()
&& action.getKind() == kindOfAction) {
CMNode actionCMNode = action.getCMNode();
if( actionCMNode == null || cmnodes.contains( actionCMNode ))
continue;
// Check element name space
// Do not include elements whose name space is not already declared
if( actionCMNode instanceof XSDElementDeclarationAdapter ) {
XSDElementDeclarationAdapter a = (XSDElementDeclarationAdapter) actionCMNode;
String nsUri = (String) a.getCMDocument().getProperty( XSDImpl.PROPERTY_TARGET_NAMESPACE_URI );
if( nsUri == null
|| DomUtils.lookupNamespacePrefix( nsUri, parentElement ) == null )
continue;
}
// Yes, we're strict: only XSD models are expected
else {
continue;
}
// Is insertion valid?
// If the parent is valid before the insertion, apply a strict validation
if( isBlockValid ) {
if( ! mQuery.canInsert( parentElement, actionCMNode, childPosition, ModelQuery.VALIDITY_STRICT ))
continue;
}
// Otherwise, use a partial one, based on the declared name spaces
else {
if( ! mQuery.canInsert( parentElement, actionCMNode, childPosition, ModelQuery.VALIDITY_PARTIAL ))
continue;
}
cmnodes.add( actionCMNode );
}
}
}
return cmnodes;
}
}