/*******************************************************************************
* Copyright (c) 2001, 2004 IBM Corporation 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:
* IBM Corporation - initial API and implementation
* Jens Lukowski/Innoopract - initial renaming/restructuring
* Exadel, Inc.
* Red Hat, Inc.
*******************************************************************************/
package org.jboss.tools.common.text.ext.hyperlink.xpl;
import java.util.ArrayList;
import java.util.List;
import org.eclipse.core.runtime.IConfigurationElement;
import org.jboss.tools.common.text.ext.hyperlink.HyperlinkBuilder;
import org.jboss.tools.common.text.ext.util.xpl.RegistryReader;
public class BaseHyperlinkBuilder extends RegistryReader{
// extension point ID
public static final String PL_HYPERLINK = "hyperlink"; //$NON-NLS-1$
// public static final String PLUGIN_ID = ExtensionsPlugin.PLUGIN_ID;
public static final String TAG_HYPERLINK = "hyperlink"; //$NON-NLS-1$
public static final String TAG_CONTENT_TYPE_IDENTIFIER = "contenttypeidentifier"; //$NON-NLS-1$
public static final String TAG_PARTITION_TYPE = "partitiontype"; //$NON-NLS-1$
public static final String ATT_ID = "id"; //$NON-NLS-1$
public static final String ATT_CLASS = "class"; //$NON-NLS-1$
protected String targetContributionTag;
private static HyperlinkBuilder fInstance;
private List fHyperlinkDefs = null;
private HyperlinkDefinition fCurrentHyperlinkDefinition = null;
private String fCurrentContentType;
/**
* returns singleton instance of HyperlinkBuilder
*
* @return HyperlinkBuilder
*/
public synchronized static HyperlinkBuilder getInstance() {
if (fInstance == null) {
fInstance = new HyperlinkBuilder();
}
return fInstance;
}
/**
* Returns the name of the part ID attribute that is expected
* in the target extension.
*
* @param element
* @return String
*/
protected String getId(IConfigurationElement element) {
String value = element.getAttribute(ATT_ID);
return value;
}
protected String getHyperlinkClass(IConfigurationElement element) {
String value = element.getAttribute(ATT_CLASS);
return value;
}
/**
* Processes element which should be a configuration element specifying an
* open on object. Creates a new open on definition object and adds it to the
* list of open on definition objects
*
* @param element hyperlink configuration element
*/
private void processHyperlinkTag(IConfigurationElement element) {
String theId = getId(element);
String theClass = getHyperlinkClass(element);
if (theId != null && theClass != null) {
// start building new HyperlinkDefinition
fCurrentHyperlinkDefinition = new HyperlinkDefinition(theId, theClass, element);
// create a new list of open on definitions if it hasnt been created yet
if (fHyperlinkDefs == null) {
fHyperlinkDefs = new ArrayList();
}
fHyperlinkDefs.add(fCurrentHyperlinkDefinition);
}
else {
fCurrentHyperlinkDefinition = null;
}
}
/**
* Processes element which should be a configuration element specifying a content
* type for the current open on tag. Assumes that there is a valid current open
* on definition object.
*
* @param element contenttypeidentifier configuration element
*/
private void processContentTypeTag(IConfigurationElement element) {
// add to current HyperlinkDefinition
String theId = getId(element);
if (theId != null) {
fCurrentContentType = theId;
fCurrentHyperlinkDefinition.addContentTypeId(fCurrentContentType);
}
else {
fCurrentContentType = null;
}
}
/**
* Processes element which should be a configuration element specifying a partition
* type for the current open on/content type tag. Assumes that there is a valid
* current open on/content type tag.
*
* @param element partitiontype configuration element
*/
private void processPartitionTypeTag(IConfigurationElement element) {
// add to current HyperlinkDefinition/contentType
String theId = getId(element);
if (theId != null) {
fCurrentHyperlinkDefinition.addPartitionType(fCurrentContentType, theId);
}
}
/* (non-Javadoc)
* @see com.ibm.sse.editor.internal.extension.RegistryReader#readElement(org.eclipse.core.runtime.IConfigurationElement)
*/
protected boolean readElement(IConfigurationElement element) {
String tag = element.getName();
if (tag.equals(targetContributionTag)) {
processHyperlinkTag(element);
// make sure processing of current open on tag resulted in a current open on definition
// before continue reading the children
if (fCurrentHyperlinkDefinition != null) {
readElementChildren(element);
}
return true;
}
else if (tag.equals(TAG_CONTENT_TYPE_IDENTIFIER)) {
processContentTypeTag(element);
// make sure processing of current content type resulted in a valid content type
// before reading the children
if (fCurrentContentType != null) {
readElementChildren(element);
}
return true;
}
else if (tag.equals(TAG_PARTITION_TYPE)) {
processPartitionTypeTag(element);
return true;
}
return false;
}
private void initCache() {
if (fHyperlinkDefs == null) {
readContributions(TAG_HYPERLINK, PL_HYPERLINK);
}
}
protected void readContributions(String tag_hyperlink2, String pl_hyperlink2) {
}
/**
* Returns all the open on definition objects
* @return
*/
public HyperlinkDefinition[] getHyperlinkDefinitions() {
initCache();
return (fHyperlinkDefs == null ? new HyperlinkDefinition[0] :
(HyperlinkDefinition[])fHyperlinkDefs.toArray(new HyperlinkDefinition[fHyperlinkDefs.size()]));
}
/**
* Returns all the open on definition objects valid for contentType/partitionType
* @param contentType
* @param partitionType
* @return if either contentType or partitionType is null, null is returned
*/
public HyperlinkDefinition[] getHyperlinkDefinitions(String contentType, String partitionType) {
if (contentType == null || partitionType == null) {
// should not be able to define an hyperlink without a content type
// but if it were possible then would need to search all hyperlink definitions for
// definitions with empty contentType list
return null;
}
// entire list of hyperlink definition objects
HyperlinkDefinition[] allDefs = getHyperlinkDefinitions();
// current list of open on definitions valid for contentType/partitionType
List defs = new ArrayList();
// default definitions that should be added to end of list of open on definitions
List lastDefs = new ArrayList();
for (int i = 0; i < allDefs.length; ++i) {
// for each one check if it contains contentType
List partitions = (List) allDefs[i].getContentTypes().get(contentType);
if (partitions != null) {
// this hyperlink definition is valid for all partition types for this content type
if (partitions.isEmpty()) {
// this will be added to end of list because this is considered a default hyperlink
lastDefs.add(allDefs[i]);
}
else {
// examine the partition types of this hyperlink
int j = 0; // current index in list of partitions
boolean added = false; // hyperlink has been added to list
while (j < partitions.size() && !added) {
// this hyperlink definition applies to partitionType so add to list of valid hyperlinks
if (partitionType.equals(partitions.get(j))) {
defs.add(allDefs[i]);
added = true;
}
else {
// continue checking to see if this hyperlink definition is valid for current partitionType
++j;
}
}
}
}
}
// append the default hyperlink definitions
defs.addAll(lastDefs);
// return the list
return (HyperlinkDefinition[]) defs.toArray(new HyperlinkDefinition[defs.size()]);
}
}