| /******************************************************************************* |
| * Copyright (c) 2006, 2011 BEA Systems, Inc. |
| * 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: |
| * wharley@bea.com - initial API and implementation |
| * philippe.marschall@netcetera.ch - Fix for 338370 |
| * IBM Corporation - Fix for validating relative name |
| *******************************************************************************/ |
| |
| package org.eclipse.jdt.internal.compiler.apt.dispatch; |
| |
| import java.io.FileNotFoundException; |
| import java.io.IOException; |
| import java.net.URI; |
| import java.util.HashSet; |
| import java.util.Iterator; |
| |
| import javax.annotation.processing.Filer; |
| import javax.annotation.processing.FilerException; |
| import javax.lang.model.element.Element; |
| import javax.tools.*; |
| import javax.tools.JavaFileManager.Location; |
| |
| import org.eclipse.jdt.internal.compiler.env.ICompilationUnit; |
| import org.eclipse.jdt.internal.compiler.lookup.ReferenceBinding; |
| |
| /** |
| * Implementation of Filer used when compilation is driven by command line |
| * or by Tool interface. This version does not need to keep track of |
| * dependencies. |
| */ |
| public class BatchFilerImpl implements Filer { |
| |
| protected final BaseAnnotationProcessorManager _dispatchManager; |
| protected final BaseProcessingEnvImpl _env; |
| protected final JavaFileManager _fileManager; |
| protected final HashSet<URI> _createdFiles; |
| |
| public BatchFilerImpl(BaseAnnotationProcessorManager dispatchManager, BatchProcessingEnvImpl env) |
| { |
| _dispatchManager = dispatchManager; |
| _fileManager = env._fileManager; |
| _env = env; |
| _createdFiles = new HashSet<URI>(); |
| } |
| |
| public void addNewUnit(ICompilationUnit unit) { |
| _env.addNewUnit(unit); |
| } |
| |
| public void addNewClassFile(ReferenceBinding binding) { |
| _env.addNewClassFile(binding); |
| } |
| |
| /* (non-Javadoc) |
| * @see javax.annotation.processing.Filer#createClassFile(java.lang.CharSequence, javax.lang.model.element.Element[]) |
| */ |
| @Override |
| public JavaFileObject createClassFile(CharSequence name, |
| Element... originatingElements) throws IOException { |
| JavaFileObject jfo = _fileManager.getJavaFileForOutput( |
| StandardLocation.CLASS_OUTPUT, name.toString(), JavaFileObject.Kind.CLASS, null); |
| URI uri = jfo.toUri(); |
| if (_createdFiles.contains(uri)) { |
| throw new FilerException("Class file already created : " + name); //$NON-NLS-1$ |
| } |
| |
| _createdFiles.add(uri); |
| return new HookedJavaFileObject(jfo, jfo.getName(), name.toString(), this); |
| } |
| |
| /* (non-Javadoc) |
| * @see javax.annotation.processing.Filer#createResource(javax.tools.JavaFileManager.Location, java.lang.CharSequence, java.lang.CharSequence, javax.lang.model.element.Element[]) |
| */ |
| @Override |
| public FileObject createResource(Location location, CharSequence pkg, |
| CharSequence relativeName, Element... originatingElements) |
| throws IOException { |
| validateName(relativeName); |
| FileObject fo = _fileManager.getFileForOutput( |
| location, pkg.toString(), relativeName.toString(), null); |
| URI uri = fo.toUri(); |
| if (_createdFiles.contains(uri)) { |
| Iterator<URI> it = _createdFiles.iterator(); |
| StringBuilder sb = new StringBuilder("\n----\n"); |
| while (it.hasNext()) { |
| URI next = it.next(); |
| sb.append(next).append("\n"); |
| } |
| throw new FilerException("createResource. Resource already created : " + location + '/' + pkg + '/' + relativeName + " --- uri = " + uri + sb.toString()); //$NON-NLS-1$ |
| } |
| |
| _createdFiles.add(uri); |
| return fo; |
| } |
| |
| private static void validateName(CharSequence relativeName) { |
| int length = relativeName.length(); |
| if (length == 0) { |
| throw new IllegalArgumentException("relative path cannot be empty"); //$NON-NLS-1$ |
| } |
| String path = relativeName.toString(); |
| if (path.indexOf('\\') != -1) { |
| // normalize the path with '/' |
| path = path.replace('\\', '/'); |
| } |
| if (path.charAt(0) == '/') { |
| throw new IllegalArgumentException("relative path is absolute"); //$NON-NLS-1$ |
| } |
| boolean hasDot = false; |
| for (int i = 0; i < length; i++) { |
| switch(path.charAt(i)) { |
| case '/' : |
| if (hasDot) { |
| throw new IllegalArgumentException("relative name " + relativeName + " is not relative"); //$NON-NLS-1$ //$NON-NLS-2$ |
| } |
| break; |
| case '.' : |
| hasDot = true; |
| break; |
| default: |
| hasDot = false; |
| } |
| } |
| if (hasDot) { |
| throw new IllegalArgumentException("relative name " + relativeName + " is not relative"); //$NON-NLS-1$ //$NON-NLS-2$ |
| } |
| } |
| |
| /* (non-Javadoc) |
| * @see javax.annotation.processing.Filer#createSourceFile(java.lang.CharSequence, javax.lang.model.element.Element[]) |
| */ |
| @Override |
| public JavaFileObject createSourceFile(CharSequence name, |
| Element... originatingElements) throws IOException { |
| JavaFileObject jfo = _fileManager.getJavaFileForOutput( |
| StandardLocation.SOURCE_OUTPUT, name.toString(), JavaFileObject.Kind.SOURCE, null); |
| URI uri = jfo.toUri(); |
| if (_createdFiles.contains(uri)) { |
| throw new FilerException("Source file already created : " + name); //$NON-NLS-1$ |
| } |
| |
| _createdFiles.add(uri); |
| // hook the file object's writers to create compilation unit and add to addedUnits() |
| return new HookedJavaFileObject(jfo, jfo.getName(), name.toString(), this); |
| } |
| |
| /* (non-Javadoc) |
| * @see javax.annotation.processing.Filer#getResource(javax.tools.JavaFileManager.Location, java.lang.CharSequence, java.lang.CharSequence) |
| */ |
| @Override |
| public FileObject getResource(Location location, CharSequence pkg, |
| CharSequence relativeName) throws IOException { |
| validateName(relativeName); |
| FileObject fo = _fileManager.getFileForInput( |
| location, pkg.toString(), relativeName.toString()); |
| if (fo == null) { |
| throw new FileNotFoundException("Resource does not exist : " + location + '/' + pkg + '/' + relativeName); //$NON-NLS-1$ |
| } |
| URI uri = fo.toUri(); |
| if (_createdFiles.contains(uri)) { |
| throw new FilerException("getResource. Resource already created : " + location + '/' + pkg + '/' + relativeName + " --- uri = " + uri); //$NON-NLS-1$ |
| } |
| |
| _createdFiles.add(uri); |
| return fo; |
| } |
| |
| } |