blob: 741b3b215742ffa6a9c00b5a37ca415d196fabf6 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2004, 2018 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
*
*******************************************************************************/
package org.eclipse.jst.jsp.core.internal.provisional.contenttype;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;
import org.eclipse.core.runtime.Platform;
import org.eclipse.core.runtime.content.IContentType;
import org.eclipse.core.runtime.content.IContentTypeManager.ContentTypeChangeEvent;
import org.eclipse.core.runtime.content.IContentTypeManager.IContentTypeChangeListener;
/**
* This class, with its one field, is a convience to provide compile-time
* safety when refering to a contentType ID. The value of the contenttype id
* field must match what is specified in plugin.xml file.
*/
public class ContentTypeIdForJSP {
/**
* The value of the contenttype id field must match what is specified in
* plugin.xml file. Note: this value is intentially set with default
* protected method so it will not be inlined.
*/
public final static String ContentTypeID_JSP = getConstantString();
/**
* The value of the contenttype id field must match what is specified in
* plugin.xml file. Note: this value is intentially set with default
* protected method so it will not be inlined.
*/
public final static String ContentTypeID_JSPFRAGMENT = getFragmentConstantString();
/**
* The value of the contenttype id field must match what is specified in
* plugin.xml file. Note: this value is intentially set with default
* protected method so it will not be inlined.
*/
public final static String ContentTypeID_JSPTAG = getTagConstantString();
static char[][] JSP_EXTENSIONS;
static char[][] JSP_FILENAMES;
private static String JSP = "jsp";
private static ContentTypeChangeListener typeChangeListener = new ContentTypeChangeListener();
/**
* Don't allow instantiation.
*/
private ContentTypeIdForJSP() {
super();
}
static String getConstantString() {
return "org.eclipse.jst.jsp.core.jspsource"; //$NON-NLS-1$
}
static String getFragmentConstantString() {
return "org.eclipse.jst.jsp.core.jspfragmentsource"; //$NON-NLS-1$
}
static String getTagConstantString() {
return "org.eclipse.jst.jsp.core.tagsource"; //$NON-NLS-1$
}
public static IContentTypeChangeListener getTypeChangeListener() {
return typeChangeListener;
}
/**
* @param fileName
* @return the first index within an array of filename extensions that
* denote the JSP content type or a subtype and match the
* extension of the given filename, or the index within an
* array of explicitly defined filenames that matches.
*/
public static int indexOfJSPExtension(String fileName) {
char[] name = fileName.toCharArray();
int fileNameLength = fileName.length();
char[][] jspExtensions = getJSPExtensions();
extensions: for (int i = 0, length = jspExtensions.length; i < length; i++) {
char[] extension = jspExtensions[i];
int extensionLength = extension.length;
int extensionStart = fileNameLength - extensionLength;
int dotIndex = extensionStart - 1;
if (dotIndex < 0) continue;
if (name[dotIndex] != '.') continue;
for (int j = 0; j < extensionLength; j++) {
if (name[extensionStart + j] != extension[j])
continue extensions;
}
return dotIndex;
}
char[][] filenames = JSP_FILENAMES;
if (filenames != null) {
for (int i = 0; i < filenames.length; i++) {
if (Arrays.equals(name, filenames[i]))
return i;
}
}
return -1;
}
/**
* @return an array of all filename extensions that are of the JSP content
* type or one of its subtypes
*/
public static char[][] getJSPExtensions() {
if (JSP_EXTENSIONS == null) {
IContentType jspContentType = Platform.getContentTypeManager().getContentType(getConstantString());
Set<String> fileExtensions = new HashSet<>();
Set<String> fileNames = new HashSet<>();
// content types derived from JSP content type should be included (https://bugs.eclipse.org/bugs/show_bug.cgi?id=121715)
IContentType[] contentTypes = Platform.getContentTypeManager().getAllContentTypes();
for (int i = 0, length = contentTypes.length; i < length; i++) {
if (contentTypes[i].isKindOf(jspContentType)) { // note that jspContentType.isKindOf(jspContentType) == true
String[] fileExtension = contentTypes[i].getFileSpecs(IContentType.FILE_EXTENSION_SPEC);
for (int j = 0; j < fileExtension.length; j++) {
fileExtensions.add(fileExtension[j]);
}
String[] names = contentTypes[i].getFileSpecs(IContentType.FILE_NAME_SPEC);
for (int j = 0; j < names.length; j++) {
fileNames.add(names[j]);
}
}
}
int length = fileExtensions.size();
// note that file extensions contains "jsp"
char[][] extensions = new char[length][];
extensions[0] = JSP.toCharArray(); // ensure that "jsp" is first
int index = 1;
Iterator<String> iterator = fileExtensions.iterator();
while (iterator.hasNext()) {
String fileExtension = iterator.next();
if (JSP.equalsIgnoreCase(fileExtension))
continue;
extensions[index++] = fileExtension.toCharArray();
}
JSP_EXTENSIONS = extensions;
char[][] names = new char[fileNames.size()][];
iterator = fileNames.iterator();
int i = 0;
while (iterator.hasNext()) {
names[i++] = iterator.next().toCharArray();
}
JSP_FILENAMES = names;
}
return JSP_EXTENSIONS;
}
static class ContentTypeChangeListener implements IContentTypeChangeListener {
@Override
public void contentTypeChanged(ContentTypeChangeEvent event) {
String id = event.getContentType().getId();
if (getConstantString().equals(id) || getFragmentConstantString().equals(id) || getTagConstantString().equals(id)) {
JSP_EXTENSIONS = null;
}
}
}
}