/**********************************************************************
* Copyright (c) 2005-2009 ant4eclipse project team.
*
* 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:
* Nils Hartmann, Daniel Kasmeroglu, Gerd Wuetherich
**********************************************************************/
package org.ant4eclipse.lib.platform.internal.model.resource.workspaceregistry;
import org.ant4eclipse.lib.core.Assure;
import org.ant4eclipse.lib.core.logging.A4ELogging;
import org.ant4eclipse.lib.platform.internal.model.resource.ChunkyFile;
import java.io.ByteArrayInputStream;
import java.io.DataInputStream;
import java.io.File;
import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;
/**
* Reads a ".location" file which provides the position of an external project from eclipse's .metadata directory.
*
*
* @author Nils Hartmann (nils@nilshartmann.net)
*/
public class LocationFileParser {
/**
* Prefix that indicates that the location of a file is not an os-path but a URI. (Eclipse >=3.2)
*/
private static final String URI_PREFIX = "URI//";
/**
* <p>
* Reads the given <code>.location</code> file and returns the <b>existing</b> path to the eclipse project directory
* stored in the <code>.location</code> file or <code>null</code> if the path doesn't point to a valid eclipse project
* directory.
* </p>
* <p>
* In opposite of {@link #readLocation(File)} this method validates the path from the .location file and only returns
* a File object if the location points to a valid Eclipse project directory.
* </p>
*
* @param locationFile
* the location file to be parsed
* @return the project directory or <code>null</code> if the location doesn't point to a valid project directory
*/
public static final File getProjectDirectory(File locationFile) {
Assure.isFile("locationFile", locationFile);
try {
// read the location of the project directory
File projectDir = readLocation(locationFile);
// check if projectDir is valid
if (projectDir != null) {
if (projectDir.isDirectory()) {
File projectfile = new File(projectDir, ".project");
if (projectfile.isFile()) {
return projectDir;
} else {
A4ELogging.debug(
"LocationFileParser.getProjectDirectory(): the project '%s' doesn't provide an Eclipse configuration",
projectDir.getAbsolutePath());
}
} else {
A4ELogging.debug("LocationFileParser.getProjectDirectory(): the stored location '%s' is not a directory",
projectDir);
}
}
} catch (IOException e) {
// TODO: Logging
e.printStackTrace();
}
// return default
return null;
}
/**
* Reads the given location file and returns the location that is stored inside the location as a File.
*
* <p>
* The file returned by this method may not exist, no check is performed here, thus you have to check for the
* existence of the file (and propably for the correct type too).
* </p>
*
* <p>
* You might want to use {@link #getProjectDirectory(File)} to receive a pointer to a valid, existing Eclipse project
* file
* </p>
*
* @param locationfile
* The file which contains the desired data.
* @return The location stored in the .location file (typically the root-folder of an external project) or null if no
* location could be read from the .location file
* @throws IOException
*/
static final File readLocation(File locationfile) throws IOException {
Assure.isFile("locationfile", locationfile);
ChunkyFile cf = new ChunkyFile(locationfile);
if (cf.getChunkCount() == 1) {
byte[] data = cf.getChunk(0);
DataInputStream datain = new DataInputStream(new ByteArrayInputStream(data));
String location = datain.readUTF();
File file = null;
if (location.length() > 0) {
/*
* see {@link org.eclipse.core.internal.resources.LocalMetaArea#readPrivateDescription(IProject target,
* IProjectDescription description)}
*/
if (location.startsWith(URI_PREFIX)) {
URI uri = URI.create(location.substring(URI_PREFIX.length()));
if (!uri.getScheme().startsWith("file")) {
A4ELogging.debug("LocationFileParser.readLocation(): the stored location uri '%s' is not a file-uri", uri);
} else {
file = new File(uri);
}
} else {
try {
// try to interprete the location as a URI
file = new File(new URI(location));
} catch (URISyntaxException ex) {
// fallback mechanism which interprets the location as a simple path
A4ELogging.debug("LocationFileParser.readLocation(): the location '%s' will be interpreted as a path",
location);
file = new File(location);
} catch (IllegalArgumentException ex) {
// fallback mechanism which interprets the location as a simple path.
// this can happen if the location doesn't conform to the current system
// (f.e. a location file for unix which is used while ANT is executed unter
// windows)
A4ELogging.debug("LocationFileParser.readLocation(): the location '%s' will be interpreted as a path",
location);
file = new File(location);
}
}
return file;
}
} else {
A4ELogging.warn("the file '%s' contains %d chunks instead of a single one", locationfile,
Integer.valueOf(cf.getChunkCount()));
}
return null;
}
}