/* * ****************************************************************************** * MontiCore Language Workbench * Copyright (c) 2015, MontiCore, All rights reserved. * * This project is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 3.0 of the License, or (at your option) any later version. * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this project. If not, see <http://www.gnu.org/licenses/>. * ****************************************************************************** */ package de.monticore.io.paths; import static com.google.common.base.Preconditions.checkState; import java.io.File; import java.io.IOException; import java.net.JarURLConnection; import java.net.URI; import java.net.URL; import java.nio.file.Path; import java.nio.file.Paths; import java.util.Objects; import org.apache.commons.io.FilenameUtils; import de.se_rwth.commons.logging.Log; final class ModelCoordinateImpl implements ModelCoordinate { /** * The relative location of the model.<br> * Example: {@code src/main/grammars/de/mc/statechart.mc} */ private URL location; /** * The qualified path of the model. It is implied that any directories * preceding the file name are part of the model package.<br> * Example: {@code de/mc/statechart.mc} */ private Path qualifiedPath; @Override public boolean hasLocation() { return this.location != null; } @Override public boolean isQualified() { return this.qualifiedPath != null; } @Override public void setLocation(URL location) { checkState(this.location == null, "The location of the ModelCoordinate was already set."); this.location = location; } @Override public void setQualifiedPath(Path qualifiedPath) { checkState(this.qualifiedPath == null, "The qualified path of the ModelCoordinate was already set."); this.qualifiedPath = qualifiedPath; } @Override public boolean exists() { checkState(location != null, "The location of the ModelCoordinate wasn't set."); return location != null; } @Override public String getBaseName() { if (hasLocation()) { return FilenameUtils.getBaseName(location.toString()); } else { return FilenameUtils.getBaseName(qualifiedPath.toString()); } } @Override public String getExtension() { if (hasLocation()) { return FilenameUtils.getExtension(location.toString()); } else { return FilenameUtils.getExtension(qualifiedPath.toString()); } } @Override public URL getLocation() { checkState(location != null, "The location of the ModelCoordinate wasn't set."); return this.location; } @Override public String getName() { if (hasLocation()) { return FilenameUtils.getName(location.toString()); } else { return FilenameUtils.getName(qualifiedPath.toString()); } } @Override public Path getPackagePath() { checkState(qualifiedPath != null, "The qualified path of the ModelCoordinate wasn't set."); return Paths.get(FilenameUtils.getPathNoEndSeparator(qualifiedPath.toString())); } @Override public Path getParentDirectoryPath() { checkState(qualifiedPath != null, "The qualified path of the ModelCoordinate wasn't set."); if (location.getProtocol().equals("jar")) { try { JarURLConnection connection = (JarURLConnection) location.openConnection(); File result = new File(connection.getJarFileURL().getFile()); return Paths.get(result.getAbsolutePath()); } catch (IOException e) { Log.debug("Error reading jar file URL", e, ModelCoordinateImpl.class.getName()); } } String locationString = location.toString(); String protocol = location.getProtocol(); int protocolLength = 0; if (locationString.startsWith(protocol)) { protocolLength = protocol.length() + 1; } int qualifiedPathLength = qualifiedPath.toString().length(); String parentDirectoryString = locationString .substring(protocolLength, locationString.length() - qualifiedPathLength); String uri = protocol + ":" + parentDirectoryString; URI temp = URI.create(uri); Path p = Paths.get(temp); return p; } @Override public String getQualifiedBaseName() { checkState(qualifiedPath != null, "The qualified path of the ModelCoordinate wasn't set."); // regex for replacing all file separators with dots return getQualifiedBasePath().toString().replaceAll("\\\\|/", "."); } @Override public Path getQualifiedBasePath() { checkState(qualifiedPath != null, "The qualified path of the ModelCoordinate wasn't set."); return getPackagePath().resolve(getBaseName()); } @Override public Path getQualifiedPath() { checkState(qualifiedPath != null, "The qualified path of the ModelCoordinate wasn't set."); return this.qualifiedPath; } @Override public boolean equals(Object obj) { if (!(obj instanceof ModelCoordinate)) { return false; } ModelCoordinate coordinate = (ModelCoordinate) obj; return Objects.equals(location, coordinate.getLocation()) && Objects.equals(qualifiedPath, coordinate.getQualifiedPath()); } @Override public int hashCode() { int hashCode = 0; hashCode += location != null ? location.hashCode() : 0; hashCode += qualifiedPath != null ? qualifiedPath.hashCode() : 0; return hashCode; } @Override public String toString() { return "Location: " + Objects.toString(location) + " Package: " + Objects.toString(qualifiedPath); } }