use of eu.esdihumboldt.hale.common.core.io.report.impl.IOMessageImpl in project hale by halestudio.
the class AbstractProjectReader method setProjectChecked.
/**
* Set the loaded project and do a version check.
*
* @param project the project to set
* @param reporter the reporter
*/
public void setProjectChecked(Project project, IOReporter reporter) {
this.project = project;
// check version
Version projectVersion = stripQualifier(project.getHaleVersion());
if (projectVersion != null) {
Version haleVersion = stripQualifier(HalePlatform.getCoreVersion());
int compared = haleVersion.compareTo(projectVersion);
if (compared < 0) {
// project is newer than HALE
String message = MessageFormat.format("The version of hale studio the loaded project was created with ({1}) is newer than this version of hale studio ({0}). Consider updating to avoid possible information loss or unexpected behavior.", haleVersion, projectVersion);
// report
reporter.warn(new IOMessageImpl(message, null));
// and log explicitly
log.userWarn(message);
} else if (compared == 0 && HalePlatform.isSnapshotVersion()) {
// same version, but used version is a SNAPSHOT version
reporter.warn(new IOMessageImpl(MessageFormat.format("You are using a SNAPSHOT version of hale studio {0} to load a project of the same version. " + "Thus there is the possibility that in the loaded project there are hale studio features used that are not yet supported by your SNAPSHOT.", haleVersion), null));
}
}
}
use of eu.esdihumboldt.hale.common.core.io.report.impl.IOMessageImpl in project hale by halestudio.
the class ArchiveProjectWriter method updateResources.
/**
* Update the resources and copy them into the target directory
*
* @param targetDirectory target directory
* @param includeWebResources whether to include web resources in the copy
* @param progress the progress indicator
* @param reporter the reporter to use for the execution report
* @throws IOException if an I/O operation fails
*/
protected void updateResources(File targetDirectory, boolean includeWebResources, ProgressIndicator progress, IOReporter reporter) throws IOException {
progress.begin("Copy resources", ProgressIndicator.UNKNOWN);
try {
List<IOConfiguration> resources = getProject().getResources();
// every resource needs his own directory
int count = 1;
// true if excluded files should be skipped; false is default
boolean excludeDataFiles = getParameter(EXLUDE_DATA_FILES).as(Boolean.class, false);
// resource locations mapped to new resource path
Map<URI, String> handledResources = new HashMap<>();
Iterator<IOConfiguration> iter = resources.iterator();
while (iter.hasNext()) {
IOConfiguration resource = iter.next();
// import not possible due to cycle errors
if (excludeDataFiles && resource.getActionId().equals("eu.esdihumboldt.hale.io.instance.read.source")) {
// delete reference in project file
iter.remove();
continue;
}
// get resource path
Map<String, Value> providerConfig = resource.getProviderConfiguration();
String path = providerConfig.get(ImportProvider.PARAM_SOURCE).toString();
URI pathUri;
try {
pathUri = new URI(path);
} catch (URISyntaxException e1) {
reporter.error(new IOMessageImpl("Skipped resource because of invalid URI: " + path, e1));
continue;
}
if (!pathUri.isAbsolute()) {
if (getPreviousTarget() != null) {
pathUri = getPreviousTarget().resolve(pathUri);
} else {
log.warn("Could not resolve relative path " + pathUri.toString());
}
}
// check if path was already handled
if (handledResources.containsKey(pathUri)) {
providerConfig.put(ImportProvider.PARAM_SOURCE, Value.of(handledResources.get(pathUri)));
// skip copying the resource
continue;
}
String scheme = pathUri.getScheme();
LocatableInputSupplier<? extends InputStream> input = null;
if (scheme != null) {
if (scheme.equals("http") || scheme.equals("https")) {
// web resource
if (includeWebResources) {
input = new DefaultInputSupplier(pathUri);
} else {
// web resource that should not be included this
// time
// but the resolved URI should be stored
// nevertheless
// otherwise the URI may be invalid if it was
// relative
providerConfig.put(ImportProvider.PARAM_SOURCE, Value.of(pathUri.toASCIIString()));
continue;
}
} else if (scheme.equals("file") || scheme.equals("platform") || scheme.equals("bundle") || scheme.equals("jar")) {
// files need always to be included
// platform resources (or other internal resources)
// should be included as well
input = new DefaultInputSupplier(pathUri);
} else {
// other type of URI, e.g. JDBC
// not to be included
providerConfig.put(ImportProvider.PARAM_SOURCE, Value.of(pathUri.toASCIIString()));
continue;
}
} else {
// now can't open that, can we?
reporter.error(new IOMessageImpl("Skipped resource because it cannot be loaded from " + pathUri.toString(), null));
continue;
}
progress.setCurrentTask("Copying resource at " + path);
// every resource file is copied into an own resource
// directory in the target directory
String resourceFolder = "resource" + count;
File newDirectory = new File(targetDirectory, resourceFolder);
try {
newDirectory.mkdir();
} catch (SecurityException e) {
throw new IOException("Can not create directory " + newDirectory.toString(), e);
}
// Extract the file name from pathUri.getPath().
// This will produce a non-URL-encoded file name to be used in
// the File(File parent, String child) constructor below
String fileName = FilenameUtils.getName(pathUri.getPath().toString());
if (path.isEmpty()) {
fileName = "file";
}
File newFile = new File(newDirectory, fileName);
Path target = newFile.toPath();
// retrieve the resource advisor
Value ct = providerConfig.get(ImportProvider.PARAM_CONTENT_TYPE);
IContentType contentType = null;
if (ct != null) {
contentType = HalePlatform.getContentTypeManager().getContentType(ct.as(String.class));
}
ResourceAdvisor ra = ResourceAdvisorExtension.getInstance().getAdvisor(contentType);
// copy the resource
progress.setCurrentTask("Copying resource at " + path);
// Extract the URL-encoded file name of the copied resource and
// build the new relative resource path
String resourceName = FilenameUtils.getName(target.toUri().toString());
String newPath = resourceFolder + "/" + resourceName;
boolean skipCopy = getParameter(EXCLUDE_CACHED_RESOURCES).as(Boolean.class, false) && !resource.getCache().isEmpty();
if (!skipCopy) {
ra.copyResource(input, target, contentType, includeWebResources, reporter);
// store new path for resource
handledResources.put(pathUri, newPath);
}
// update the provider configuration
providerConfig.put(ImportProvider.PARAM_SOURCE, Value.of(newPath));
count++;
}
} finally {
progress.end();
}
}
use of eu.esdihumboldt.hale.common.core.io.report.impl.IOMessageImpl in project hale by halestudio.
the class DefaultProjectReader method execute.
/**
* @see AbstractIOProvider#execute(ProgressIndicator, IOReporter)
*/
@Override
protected IOReport execute(ProgressIndicator progress, IOReporter reporter) throws IOProviderConfigurationException, IOException {
progress.begin("Load project", ProgressIndicator.UNKNOWN);
InputStream in = getSource().getInput();
if (archive) {
// read from archive
ZipInputStream zip = new ZipInputStream(new BufferedInputStream(in));
try {
ZipEntry entry;
while ((entry = zip.getNextEntry()) != null) {
String name = entry.getName();
progress.setCurrentTask(MessageFormat.format("Load {0}", name));
if (name.equals(ProjectIO.PROJECT_FILE)) {
try {
setProjectChecked(Project.load(new EntryInputStream(zip)), reporter);
} catch (Exception e) {
// fail if main project file cannot be loaded
throw new IOProviderConfigurationException("Source is no valid project archive", e);
}
} else {
ProjectFile file = getProjectFiles().get(name);
if (file != null) {
try {
file.load(new EntryInputStream(zip));
} catch (Exception e) {
reporter.error(new IOMessageImpl("Error while loading project file {0}, file will be reset.", e, -1, -1, name));
// reset file
file.reset();
}
}
}
}
} finally {
zip.close();
}
} else {
// read from XML
try {
setProjectChecked(Project.load(in), reporter);
} catch (Exception e) {
// fail if main project file cannot be loaded
throw new IOProviderConfigurationException("Source is no valid project file", e);
} finally {
in.close();
}
}
URI oldProjectLocation;
if (getProject().getSaveConfiguration() == null) {
oldProjectLocation = getSource().getLocation();
} else {
oldProjectLocation = URI.create(getProject().getSaveConfiguration().getProviderConfiguration().get(ExportProvider.PARAM_TARGET).as(String.class));
}
PathUpdate update = new PathUpdate(oldProjectLocation, getSource().getLocation());
// check if there are any external project files listed
if (getProjectFiles() != null) {
// only if project files set at all
for (ProjectFileInfo fileInfo : getProject().getProjectFiles()) {
ProjectFile projectFile = getProjectFiles().get(fileInfo.getName());
if (projectFile != null) {
URI location = fileInfo.getLocation();
location = update.findLocation(location, false, DefaultInputSupplier.SCHEME_LOCAL.equals(getSource().getLocation().getScheme()), false);
if (location == null && getSource().getLocation() != null) {
// 1st try: appending file name to project location
try {
URI candidate = new URI(getSource().getLocation().toString() + "." + fileInfo.getName());
if (HaleIO.testStream(candidate, true)) {
location = candidate;
}
} catch (URISyntaxException e) {
// ignore
}
// 2nd try: file name next to project
if (location != null) {
try {
String projectLoc = getSource().getLocation().toString();
int index = projectLoc.lastIndexOf('/');
if (index > 0) {
URI candidate = new URI(projectLoc.substring(0, index + 1) + fileInfo.getName());
if (HaleIO.testStream(candidate, true)) {
location = candidate;
}
}
} catch (URISyntaxException e) {
// ignore
}
}
}
boolean fileSuccess = false;
if (location != null) {
try {
DefaultInputSupplier dis = new DefaultInputSupplier(location);
try (InputStream input = dis.getInput()) {
projectFile.load(input);
fileSuccess = true;
} catch (Exception e) {
// hand down
throw e;
}
} catch (Exception e) {
reporter.error(new IOMessageImpl("Loading project file failed", e));
}
}
if (!fileSuccess) {
reporter.error(new IOMessageImpl("Error while loading project file {0}, file will be reset.", null, -1, -1, fileInfo.getName()));
projectFile.reset();
}
} else {
reporter.info(new IOMessageImpl("No handler for external project file {0} found.", null, -1, -1, fileInfo.getName()));
}
}
}
// clear project infos
/*
* XXX was there any particular reason why this was done? I suspect it
* was done so when saving the project this information is not saved
* again as-is, but on the basis of actual files written. However, this
* case is handled in the project writer already.
*
* As this information is in fact necessary when trying to identify
* certain files like the alignment, clearing the list of project files
* was commented out.
*/
// getProject().getProjectFiles().clear();
progress.end();
reporter.setSuccess(true);
return reporter;
}
use of eu.esdihumboldt.hale.common.core.io.report.impl.IOMessageImpl in project hale by halestudio.
the class DefaultProjectWriter method execute.
/**
* @see AbstractIOProvider#execute(ProgressIndicator, IOReporter)
*/
@Override
protected IOReport execute(ProgressIndicator progress, IOReporter reporter) throws IOProviderConfigurationException, IOException {
boolean separateProjectFiles = !archive || isUseSeparateFiles();
URI targetLocation = getTarget().getLocation();
File targetFile;
try {
targetFile = new File(targetLocation);
} catch (Exception e) {
if (!archive) {
// cannot save as XML if it's not a file
reporter.error(new IOMessageImpl("Could not determine project file path.", e));
reporter.setSuccess(false);
return reporter;
}
targetFile = null;
// if it's not a file, we must save the project files inside the zip
// stream
separateProjectFiles = false;
}
int entries = 1;
if (getProjectFiles() != null) {
entries += getProjectFiles().size();
}
progress.begin("Save project", entries);
// clear project file information that may already be contained in the
// project
getProject().getProjectFiles().clear();
// files
if (separateProjectFiles && targetFile != null) {
for (Entry<String, ProjectFile> entry : getProjectFiles().entrySet()) {
String name = entry.getKey();
// determine target file for project file
String projectFileName = targetFile.getName() + "." + name;
final File pfile = new File(targetFile.getParentFile(), projectFileName);
// the following line is basically
// URI.create(escape(projectFileName))
URI relativeProjectFile = targetFile.getParentFile().toURI().relativize(pfile.toURI());
// add project file information to project
getProject().getProjectFiles().add(new ProjectFileInfo(name, relativeProjectFile));
// write entry
ProjectFile file = entry.getValue();
try {
LocatableOutputSupplier<OutputStream> target = new LocatableOutputSupplier<OutputStream>() {
@Override
public OutputStream getOutput() throws IOException {
return new BufferedOutputStream(new FileOutputStream(pfile));
}
@Override
public URI getLocation() {
return pfile.toURI();
}
};
file.store(target);
} catch (Exception e) {
reporter.error(new IOMessageImpl("Error saving a project file.", e));
reporter.setSuccess(false);
return reporter;
}
progress.advance(1);
}
}
updateRelativeResourcePaths(getProject().getResources(), getPreviousTarget(), targetLocation);
if (archive) {
// save to archive
final ZipOutputStream zip = new ZipOutputStream(new BufferedOutputStream(getTarget().getOutput()));
try {
// write main entry
zip.putNextEntry(new ZipEntry(ProjectIO.PROJECT_FILE));
try {
Project.save(getProject(), new EntryOutputStream(zip));
} catch (Exception e) {
reporter.error(new IOMessageImpl("Could not save main project configuration.", e));
reporter.setSuccess(false);
return reporter;
}
zip.closeEntry();
progress.advance(1);
// write additional project files to zip stream
if (getProjectFiles() != null && !separateProjectFiles) {
for (Entry<String, ProjectFile> entry : getProjectFiles().entrySet()) {
String name = entry.getKey();
if (name.equalsIgnoreCase(ProjectIO.PROJECT_FILE)) {
reporter.error(new IOMessageImpl("Invalid file name {0}. File name may not match the name of the main project configuration.", null, -1, -1, name));
} else {
// write entry
zip.putNextEntry(new ZipEntry(name));
ProjectFile file = entry.getValue();
try {
LocatableOutputSupplier<OutputStream> target = new LocatableOutputSupplier<OutputStream>() {
private boolean first = true;
@Override
public OutputStream getOutput() throws IOException {
if (first) {
first = false;
return new EntryOutputStream(zip);
}
throw new IllegalStateException("Output stream only available once");
}
@Override
public URI getLocation() {
return getTarget().getLocation();
}
};
file.store(target);
} catch (Exception e) {
reporter.error(new IOMessageImpl("Error saving a project file.", e));
reporter.setSuccess(false);
return reporter;
}
zip.closeEntry();
}
progress.advance(1);
}
}
} finally {
zip.close();
}
} else {
// save project file to XML
OutputStream out = getTarget().getOutput();
try {
Project.save(getProject(), out);
} catch (Exception e) {
reporter.error(new IOMessageImpl("Could not save main project file.", e));
reporter.setSuccess(false);
return reporter;
} finally {
out.close();
}
progress.advance(1);
}
reporter.setSuccess(true);
return reporter;
}
use of eu.esdihumboldt.hale.common.core.io.report.impl.IOMessageImpl in project hale by halestudio.
the class XMLPathUpdater method update.
/**
* Actual implementation of the update method.
*
* @param xmlResource the XML resource file that gets updated
* @param oldPath its original location
* @param locationXPath a XPath expression to find nodes that should be
* processed
* @param includeWebResources whether web resources should be copied and
* updates, too
* @param reporter the reporter of the current IO process where errors
* should be reported to
* @param updates a map of already copied files which is used and gets
* filled by this method. Needed for multiple updates on the same
* file.
* @throws IOException if an IO exception occurs
*/
private static void update(File xmlResource, URI oldPath, String locationXPath, boolean includeWebResources, IOReporter reporter, Map<URI, File> updates) throws IOException {
// every XML resource should be updated (and copied) only once
// so we save the currently adapted resource in a map
updates.put(oldPath, xmlResource);
// counter for the directory because every resource should have its own
// directory
int count = 0;
DocumentBuilder builder = null;
try {
builder = DocumentBuilderFactory.newInstance().newDocumentBuilder();
} catch (ParserConfigurationException e) {
throw new IOException("Can not create a DocumentBuilder", e);
}
builder.setEntityResolver(new EntityResolver() {
@Override
public InputSource resolveEntity(String publicId, String systemId) throws SAXException, IOException {
// FIXME some documentation would be nice why this is OK here?!
return new InputSource(new StringReader(""));
}
});
Document doc = null;
try {
doc = builder.parse(xmlResource);
} catch (SAXException e1) {
// if the file is no XML file simply stop the recursion
return;
}
// find schemaLocation of imports/includes via XPath
XPath xpath = XPathFactory.newInstance().newXPath();
NodeList nodelist = null;
try {
nodelist = ((NodeList) xpath.evaluate(locationXPath, doc, XPathConstants.NODESET));
} catch (XPathExpressionException e) {
throw new IOException("The XPath expression is wrong", e);
}
// iterate over all imports or includes and get the schemaLocations
for (int i = 0; i < nodelist.getLength(); i++) {
Node locationNode = nodelist.item(i);
String location = locationNode.getNodeValue();
URI locationUri = null;
try {
locationUri = new URI(location);
} catch (Exception e1) {
reporter.error(new IOMessageImpl("The location is no valid URI.", e1));
continue;
}
if (!locationUri.isAbsolute()) {
locationUri = oldPath.resolve(locationUri);
}
String scheme = locationUri.getScheme();
InputStream input = null;
if (scheme != null) {
// should the resource be included?
if (includeWebResources || !(scheme.equals("http") || scheme.equals("https"))) {
DefaultInputSupplier supplier = new DefaultInputSupplier(locationUri);
input = supplier.getInput();
} else
continue;
} else {
// file is invalid - at least report that
reporter.error(new IOMessageImpl("Skipped resource because it cannot be loaded from " + locationUri.toString(), null));
continue;
}
// every file needs its own directory because of name conflicts
String filename = location;
if (location.contains("/"))
filename = location.substring(location.lastIndexOf("/") + 1);
filename = count + "/" + filename;
File includednewFile = null;
if (updates.containsKey(locationUri)) {
// if the current XML schema is already updated we have to
// find the relative path to this resource
URI relative = IOUtils.getRelativePath(updates.get(locationUri).toURI(), xmlResource.toURI());
locationNode.setNodeValue(relative.toString());
} else if (input != null) {
// we need the directory of the file
File xmlResourceDir = xmlResource.getParentFile();
// path where the file should be copied to
includednewFile = new File(xmlResourceDir, filename);
try {
includednewFile.getParentFile().mkdirs();
} catch (SecurityException e) {
throw new IOException("Can not create directories " + includednewFile.getParent(), e);
}
// copy to new directory
OutputStream output = new FileOutputStream(includednewFile);
ByteStreams.copy(input, output);
output.close();
input.close();
// set new location in the XML resource
locationNode.setNodeValue(filename);
update(includednewFile, locationUri, locationXPath, includeWebResources, reporter, updates);
count++;
}
// write new XML-File
TransformerFactory transformerFactory = TransformerFactory.newInstance();
Transformer transformer = null;
try {
transformer = transformerFactory.newTransformer();
} catch (TransformerConfigurationException e) {
log.debug("Can not create transformer for creating XMl file", e);
return;
}
DOMSource source = new DOMSource(doc);
StreamResult result = new StreamResult(xmlResource);
try {
transformer.transform(source, result);
} catch (TransformerException e) {
log.debug("Cannot create new XML file", e);
return;
}
}
}
Aggregations