blob: 8be67c367bb825099f7d81b5bf24f4315df771e1 [file] [log] [blame]
/**********************************************************************
Copyright (c)2002 IBM Corp. and others.
All rights reserved.   This program and the accompanying materials
are made available under the terms of the Common Public License v0.5
which accompanies this distribution, and is available at
http://www.eclipse.org/legal/cpl-v05.html
 
Contributors:
IBM Corporation - initial API and implementation
**********************************************************************/
package org.eclipse.jdt.core;
import java.io.File;
import java.io.IOException;
import java.util.Map;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IConfigurationElement;
import org.eclipse.core.runtime.IExtension;
import org.eclipse.core.runtime.IExtensionPoint;
import org.eclipse.core.runtime.IPluginDescriptor;
import org.eclipse.core.runtime.Plugin;
import org.eclipse.jdt.core.compiler.IScanner;
import org.eclipse.jdt.core.util.ClassFormatException;
import org.eclipse.jdt.core.util.IClassFileDisassembler;
import org.eclipse.jdt.core.util.IClassFileReader;
import org.eclipse.jdt.internal.compiler.parser.Scanner;
import org.eclipse.jdt.internal.compiler.util.Util;
import org.eclipse.jdt.internal.core.JavaModelManager;
import org.eclipse.jdt.internal.core.util.ClassFileReader;
import org.eclipse.jdt.internal.core.util.Disassembler;
import org.eclipse.jdt.internal.formatter.CodeFormatter;
/**
* Factory for creating various compiler tools, such as scanners, parsers and compilers.
*
* @since 2.0
*/
public class ToolFactory {
/**
* Create an instance of a code formatter. A code formatter implementation can be contributed via the
* extension point "org.eclipse.jdt.core.codeFormatter". If unable to find a registered extension, the factory
* will default to using the default code formatter.
*
* @see ICodeFormatter
* @see ToolFactory#createDefaultCodeFormatter(Map)
*/
public static ICodeFormatter createCodeFormatter(){
Plugin jdtCorePlugin = JavaCore.getPlugin();
if (jdtCorePlugin == null) return null;
IExtensionPoint extension = jdtCorePlugin.getDescriptor().getExtensionPoint(JavaModelManager.FORMATTER_EXTPOINT_ID);
if (extension != null) {
IExtension[] extensions = extension.getExtensions();
for(int i = 0; i < extensions.length; i++){
IConfigurationElement [] configElements = extensions[i].getConfigurationElements();
IPluginDescriptor plugin = extension.getDeclaringPluginDescriptor();
if (plugin.isPluginActivated()) {
for(int j = 0; j < configElements.length; j++){
try {
Object execExt = configElements[j].createExecutableExtension("class"); //$NON-NLS-1$
if (execExt instanceof ICodeFormatter){
// use first contribution found
return (ICodeFormatter)execExt;
}
} catch(CoreException e){
}
}
}
}
}
// no proper contribution found, use default formatter
return createDefaultCodeFormatter(null);
}
/**
* Create an instance of the buit-in code formatter. A code formatter implementation can be contributed via the
* extension point "org.eclipse.jdt.core.codeFormatter". If unable to find a registered extension, the factory will
* default to using the default code formatter.
*
* @param options - the options map to use for formatting with the default code formatter. Recognized options
* are documented on <code>JavaCore#getDefaultOptions()</code>. If set to <code>null</code>, then use
* the current settings from <code>JavaCore#getOptions</code>.
*
* @see ICodeFormatter
* @see ToolFactory#createCodeFormatter()
* @see JavaCore#getOptions()
*/
public static ICodeFormatter createDefaultCodeFormatter(Map options){
if (options == null) options = JavaCore.getOptions();
return new CodeFormatter(options);
}
/**
* Create a classfile bytecode disassembler, able to produce a String representation of a given classfile.
*
* @see IClassFileDisassembler
*/
public static IClassFileDisassembler createDefaultClassFileDisassembler(){
return new Disassembler();
}
/**
* Create a default classfile reader, able to expose the internal representation of a given classfile
* according to the decoding flag used to initialize the reader.
* Answer null if the file named fileName doesn't represent a valid .class file.
*
* The decoding flags are described in IClassFileReader.
*
* @param fileName the name of the file to be read
* @param decodingFlag the flag used to decode the class file reader.
* @return IClassFileReader
*
* @see IClassFileReader
*/
public static IClassFileReader createDefaultClassFileReader(String fileName, int decodingFlag){
try {
return new ClassFileReader(Util.getFileByteContent(new File(fileName)), decodingFlag);
} catch(ClassFormatException e) {
return null;
} catch(IOException e) {
return null;
}
}
/**
* Create a default classfile reader, able to expose the internal representation of a given classfile
* according to the decoding flag used to initialize the reader.
* Answer null if the file named zipFileName doesn't represent a valid zip file or if the zipEntryName
* is not a valid entry name for the specified zip file or if the bytes don't represent a valid
* .class file according to the JVM specifications.
*
* The decoding flags are described in IClassFileReader.
*
* @param zipFileName the name of the zip file
* @param zipEntryName the name of the entry in the zip file to be read
* @param decodingFlag the flag used to decode the class file reader.
* @return IClassFileReader
* @see IClassFileReader
*/
public static IClassFileReader createDefaultClassFileReader(String zipFileName, String zipEntryName, int decodingFlag){
try {
ZipFile zipFile = new ZipFile(zipFileName);
ZipEntry zipEntry = zipFile.getEntry(zipEntryName);
if (zipEntry == null) {
return null;
}
if (!zipEntryName.toLowerCase().endsWith(".class")) {//$NON-NLS-1$
return null;
}
byte classFileBytes[] = Util.getZipEntryByteContent(zipEntry, zipFile);
return new ClassFileReader(classFileBytes, decodingFlag);
} catch(ClassFormatException e) {
return null;
} catch(IOException e) {
return null;
}
}
/**
* Create a scanner, indicating the level of detail requested for tokenizing. The scanner can then be
* used to tokenize some source in a Java aware way.
* Here is a typical scanning loop:
*
* <code>
* IScanner scanner = ToolFactory.createScanner(false, false, false, false);
* scanner.setSource("int i = 0;".toCharArray());
* while (true) {
* int token = scanner.getNextToken();
* if (token == ITerminalSymbols.TokenNameEOF) break;
* System.out.println(token + " : " + new String(scanner.getCurrentTokenSource()));
* }
* </code>
*
* @return IScanner
*
* @param tokenizeComments - if set to <code>false</code>, comments will be silently consumed
* @param tokenizeWhiteSpace - if set to <code>false</code>, white spaces will be silently consumed,
@param assertKeyword - if set to <code>false</code>, occurrences of 'assert' will be reported as identifiers
* (<code>ITerminalSymbols#TokenNameIdentifier</code>), whereas if set to <code>true</code>, it
* would report assert keywords (<code>ITerminalSymbols#TokenNameassert</code>). Java 1.4 has introduced
* a new 'assert' keyword.
* @param recordLineSeparator - if set to <code>true</code>, the scanner will record positions of encountered line
* separator ends. In case of multi-character line separators, the last character position is considered. These positions
* can then be extracted using <code>IScanner#getLineEnds</code>
*
* @see IScanner
*/
public static IScanner createScanner(boolean tokenizeComments, boolean tokenizeWhiteSpace, boolean assertMode, boolean recordLineSeparator){
Scanner scanner = new Scanner(tokenizeComments, tokenizeWhiteSpace, false, assertMode);
scanner.recordLineSeparator = recordLineSeparator;
return scanner;
}
}