Commit 1cf6605c authored by Riegel's avatar Riegel
Browse files

Docs: Add Javadoc

parent 569ad96a
Pipeline #10989 passed with stage
in 1 minute and 27 seconds
...@@ -18,6 +18,10 @@ import java.util.zip.ZipEntry; ...@@ -18,6 +18,10 @@ import java.util.zip.ZipEntry;
import java.util.zip.ZipFile; import java.util.zip.ZipFile;
import java.util.zip.ZipInputStream; import java.util.zip.ZipInputStream;
/**
* This class serves as a representation of a ZIP-archive containing CityGml files. The contained files are represented
* by {@link CityGmlZipEntry} objects.
*/
public class CityGmlZipArchive implements Serializable { public class CityGmlZipArchive implements Serializable {
private static final Logger logger = LogManager.getLogger(CityGmlZipArchive.class); private static final Logger logger = LogManager.getLogger(CityGmlZipArchive.class);
...@@ -29,7 +33,13 @@ public class CityGmlZipArchive implements Serializable { ...@@ -29,7 +33,13 @@ public class CityGmlZipArchive implements Serializable {
private final Path archivePath; private final Path archivePath;
private final String archiveNameRE; private final String archiveNameRE;
/**
* Registers a ZIP-file as an archive. All contained XML and GML files will be registered as {@link CityGmlZipEntry} objects.
*
* @param zipFile path of the ZIP-file
* @return A {@link CityGmlZipArchive} object representing the archive, or null if read-access for the ZIP-file was denied
* @throws MalformedZipFileException if the ZIP-file has encoding errors
*/
public static CityGmlZipArchive register(String zipFile) throws MalformedZipFileException { public static CityGmlZipArchive register(String zipFile) throws MalformedZipFileException {
ArrayList<CityGmlZipEntry> archiveEntries = new ArrayList<>(); ArrayList<CityGmlZipEntry> archiveEntries = new ArrayList<>();
CityGmlZipArchive cgmlArchive = new CityGmlZipArchive(Path.of(zipFile)); CityGmlZipArchive cgmlArchive = new CityGmlZipArchive(Path.of(zipFile));
...@@ -40,6 +50,7 @@ public class CityGmlZipArchive implements Serializable { ...@@ -40,6 +50,7 @@ public class CityGmlZipArchive implements Serializable {
continue; continue;
} }
if (ze.getName().endsWith(".gml") || ze.getName().endsWith(".xml")) { if (ze.getName().endsWith(".gml") || ze.getName().endsWith(".xml")) {
// Ignore report files generated by CityDoctor
if (ze.getName().endsWith("_report.xml")) { if (ze.getName().endsWith("_report.xml")) {
continue; continue;
} }
...@@ -62,6 +73,11 @@ public class CityGmlZipArchive implements Serializable { ...@@ -62,6 +73,11 @@ public class CityGmlZipArchive implements Serializable {
} }
} }
/**
* Attempts to load all contained {@link CityGmlZipEntry} objects into memory.
*
* @param config Parser configuration for the entries
*/
public void mountArchive(ParserConfiguration config) { public void mountArchive(ParserConfiguration config) {
try (ZipFile zip = new ZipFile(archivePath.toFile())) { try (ZipFile zip = new ZipFile(archivePath.toFile())) {
for (CityGmlZipEntry entry : entries) { for (CityGmlZipEntry entry : entries) {
...@@ -79,34 +95,55 @@ public class CityGmlZipArchive implements Serializable { ...@@ -79,34 +95,55 @@ public class CityGmlZipArchive implements Serializable {
private void setEntries(List<CityGmlZipEntry> entries) { private void setEntries(List<CityGmlZipEntry> entries) {
this.entries = entries; this.entries = entries;
entries.forEach(e -> e.setArchive(this));
} }
/**
* Saves this archive as a ZIP-file.
* @param path target path for the export
*/
public void exportToZipFile(String path) { public void exportToZipFile(String path) {
ArchivePacker.packArchive(path, this); ArchivePacker.packArchive(path, this);
} }
/**
public CityGmlZipEntry getEntry(String fileName) { * Gets an entry in this archive by its subpath.
fileName = stripArchivePath(fileName); *
* @param subpath subpath to the entry from this archive's root directory
* @return the corresponding entry, or null if entry could not be found
*/
public CityGmlZipEntry getEntry(String subpath) {
subpath = stripArchivePath(subpath);
for (CityGmlZipEntry entry : entries) { for (CityGmlZipEntry entry : entries) {
String entryName = stripArchivePath(entry.getEntrySubPath()); String entryName = stripArchivePath(entry.getEntrySubPath());
if (entryName.equals(fileName)) { if (entryName.equals(subpath)) {
return entry; return entry;
} }
} }
return null; return null;
} }
/**
* Strips the root directory name of this archive from an entry subpath.
* @param path the relative path to the entry
* @return String of the path without the root directory
*/
private String stripArchivePath(String path) { private String stripArchivePath(String path) {
Path systemPath = Path.of(path); Path systemPath = Path.of(path);
return systemPath.toString().replace(archiveNameRE, ""); return systemPath.toString().replace(archiveNameRE, "");
} }
/**
* Gets the path to the ZIP-file associated with this archive.
* @return path of the ZIP-file
*/
public Path getArchivePath() { public Path getArchivePath() {
return archivePath; return archivePath;
} }
/**
* Gets the entry list of this archive.
* @return the entry list
*/
public List<CityGmlZipEntry> getEntries() { public List<CityGmlZipEntry> getEntries() {
return entries; return entries;
} }
......
...@@ -15,6 +15,11 @@ import java.io.Serializable; ...@@ -15,6 +15,11 @@ import java.io.Serializable;
import java.nio.file.Path; import java.nio.file.Path;
import java.util.zip.ZipEntry; import java.util.zip.ZipEntry;
/**
* This class serves as a representation of a CityGml file in a ZIP archive.
* <p/>
* The {@link CityDoctorModel} of the associated file can only be accessed after loading the corresponding entry.
*/
public class CityGmlZipEntry implements Serializable { public class CityGmlZipEntry implements Serializable {
private static final Logger logger = LogManager.getLogger(CityGmlZipEntry.class); private static final Logger logger = LogManager.getLogger(CityGmlZipEntry.class);
...@@ -31,16 +36,28 @@ public class CityGmlZipEntry implements Serializable { ...@@ -31,16 +36,28 @@ public class CityGmlZipEntry implements Serializable {
private static final long MB = 1024 * 1024L; private static final long MB = 1024 * 1024L;
private ZipEntryErrorType errorType = null; private ZipEntryErrorType errorType = null;
public static CityGmlZipEntry of(ZipEntry entry, CityGmlZipArchive parentArchive, ParserConfiguration config) {
CityGmlZipEntry ze = CityGmlZipEntry.register(entry, parentArchive);
ze.loadEntry(config);
return ze;
}
/**
* Attempts to parse the CityGML model associated with this entry and loads it into memory.
* <p/>
* In the event of a parsing error, the entry will be flagged by assigning the appropriate
* {@link ZipEntryErrorType} to the errorType field.
*
* @param config Parser configuration for this model
*/
public void loadEntry(ParserConfiguration config) { public void loadEntry(ParserConfiguration config) {
loadEntry(config, null); loadEntry(config, null);
} }
/**
* Attempts to parse the CityGML model associated with this entry and loads it into memory.
* <p/>
* In the event of a parsing error, the entry will be flagged by assigning the appropriate
* {@link ZipEntryErrorType} to the errorType field.
*
* @param config Parser configuration for this model
* @param l ProgressListener for tracking parsing progress
*/
public void loadEntry(ParserConfiguration config, ProgressListener l) { public void loadEntry(ParserConfiguration config, ProgressListener l) {
if (inMemory) { if (inMemory) {
return; return;
...@@ -61,6 +78,16 @@ public class CityGmlZipEntry implements Serializable { ...@@ -61,6 +78,16 @@ public class CityGmlZipEntry implements Serializable {
} }
} }
/**
* Registers a {@link ZipEntry ZipEntry} in a ZIP-archive as a {@link CityGmlZipEntry}.
* <p/>
* If the filesize of the associated file exceeds the total available system memory, or read access is denied,
* the entry will be flagged by assigning the appropriate {@link ZipEntryErrorType} to the errorType field.
*
* @param entry The ZipEntry object
* @param parentArchive The parent archive for this entry
* @return A corresponding CityGmlZipEntry object
*/
public static CityGmlZipEntry register(ZipEntry entry, CityGmlZipArchive parentArchive) { public static CityGmlZipEntry register(ZipEntry entry, CityGmlZipArchive parentArchive) {
CityGmlZipEntry cgzEntry = new CityGmlZipEntry(entry, parentArchive, false); CityGmlZipEntry cgzEntry = new CityGmlZipEntry(entry, parentArchive, false);
try { try {
...@@ -74,6 +101,12 @@ public class CityGmlZipEntry implements Serializable { ...@@ -74,6 +101,12 @@ public class CityGmlZipEntry implements Serializable {
return cgzEntry; return cgzEntry;
} }
/**
* Checks if the filesize of this entry would exceed the system's available memory.
*
* @return true if within limits, false otherwise
* @throws IOException if read access to the ZIP-archive is denied
*/
private boolean entrySizeWithinMemoryLimits() throws IOException { private boolean entrySizeWithinMemoryLimits() throws IOException {
long memoryLimit = (long) Math.ceil(((double) Runtime.getRuntime().maxMemory() / MB) * 0.9); long memoryLimit = (long) Math.ceil(((double) Runtime.getRuntime().maxMemory() / MB) * 0.9);
if (fileSize == -1L) { if (fileSize == -1L) {
...@@ -103,31 +136,43 @@ public class CityGmlZipEntry implements Serializable { ...@@ -103,31 +136,43 @@ public class CityGmlZipEntry implements Serializable {
this.parentArchive = parentArchive; this.parentArchive = parentArchive;
} }
public void setArchive(CityGmlZipArchive archive) { /**
parentArchive = archive; * Gets the parent archive of this entry.
} * @return the archive
*/
public CityGmlZipArchive getArchive() { public CityGmlZipArchive getArchive() {
return parentArchive; return parentArchive;
} }
/** /**
* Gets this entry's sub-path in the archive. * Gets the sub-path in the archive of the file associated with this entry.
* *
* @return Relative sub-path from the archive root directory. * @return the relative sub-path from the archive root directory
*/ */
public String getEntrySubPath() { public String getEntrySubPath() {
return fileName; return fileName;
} }
/**
* Gets the name of the file associated with this entry.
* @return the filename
*/
public String getDisplayName() { public String getDisplayName() {
return displayName; return displayName;
} }
/**
* Gets the {@link ZipEntryErrorType} of this entry.
* @return the error type, or null if this entry is not erroneous
*/
public ZipEntryErrorType getErrorType() { public ZipEntryErrorType getErrorType() {
return errorType; return errorType;
} }
/**
* Gets the {@link CityDoctorModel} of this entry.
* @return The model, or null if the entry has not been loaded or is erroneous
*/
public CityDoctorModel getModel() { public CityDoctorModel getModel() {
return model; return model;
} }
...@@ -136,14 +181,20 @@ public class CityGmlZipEntry implements Serializable { ...@@ -136,14 +181,20 @@ public class CityGmlZipEntry implements Serializable {
fileSize = size; fileSize = size;
} }
/**
* Resolves the reference path of a {@link de.hft.stuttgart.citydoctor2.datastructure.LibraryObject LibraryObject}
* in the {@link CityDoctorModel} of this entry.
* @param libraryObjectPath The reference path to the LibraryObject's CityGml file
* @return Relative sub-path within the archive to the CityGml file
*/
public Path resolveLibraryObjectPath(String libraryObjectPath) { public Path resolveLibraryObjectPath(String libraryObjectPath) {
return filePath.getParent().resolve(libraryObjectPath); return filePath.getParent().resolve(libraryObjectPath);
} }
/** /**
* Returns whether this entry has been loaded into memory. * Checks if the {@link CityDoctorModel} of this entry has been loaded into memory.
* *
* @return true if * @return true if it is loaded, false otherwise
*/ */
public boolean isLoaded() { public boolean isLoaded() {
return inMemory; return inMemory;
...@@ -152,7 +203,7 @@ public class CityGmlZipEntry implements Serializable { ...@@ -152,7 +203,7 @@ public class CityGmlZipEntry implements Serializable {
/** /**
* Returns the estimated uncompressed filesize of this entry. * Returns the estimated uncompressed filesize of this entry.
* *
* @return filesize in bytes, -1 if filesize unknown * @return filesize in bytes, -1L if filesize is unknown
*/ */
public long getFileSize() { public long getFileSize() {
return fileSize; return fileSize;
......
...@@ -6,6 +6,12 @@ import java.io.InputStream; ...@@ -6,6 +6,12 @@ import java.io.InputStream;
import java.util.zip.ZipEntry; import java.util.zip.ZipEntry;
import java.util.zip.ZipFile; import java.util.zip.ZipFile;
/**
* This class serves as a resource for read-access to the file that is being represented by
* a CityGmlZipEntry object.
* <p/>
* Does not decompress the file or the parent ZIP-archive.
*/
public class CityGmlZipEntryFile implements AutoCloseable { public class CityGmlZipEntryFile implements AutoCloseable {
private final ZipFile zip; private final ZipFile zip;
...@@ -13,6 +19,12 @@ public class CityGmlZipEntryFile implements AutoCloseable { ...@@ -13,6 +19,12 @@ public class CityGmlZipEntryFile implements AutoCloseable {
private final CityGmlZipEntry cgmlZipEntry; private final CityGmlZipEntry cgmlZipEntry;
private boolean closed = false; private boolean closed = false;
/**
* Creates a {@link CityGmlZipEntryFile} for a {@link CityGmlZipEntry} object's referenced file.
*
* @param entry the requested entry
* @throws IOException if read access to the ZIP-archive is denied.
*/
public CityGmlZipEntryFile(CityGmlZipEntry entry) throws IOException { public CityGmlZipEntryFile(CityGmlZipEntry entry) throws IOException {
CityGmlZipArchive archive = entry.getArchive(); CityGmlZipArchive archive = entry.getArchive();
zip = new ZipFile(archive.getArchivePath().toFile()); zip = new ZipFile(archive.getArchivePath().toFile());
...@@ -20,6 +32,14 @@ public class CityGmlZipEntryFile implements AutoCloseable { ...@@ -20,6 +32,14 @@ public class CityGmlZipEntryFile implements AutoCloseable {
this.cgmlZipEntry = entry; this.cgmlZipEntry = entry;
} }
/**
* Gets a new InputStream of this file.
* <p/>
* Returned streams are independent of each other, but will all be closed when the {@link CityGmlZipEntryFile} object
* is closed.
* @return an InputStream of this file.
* @throws IOException when this method is called after the file has been closed.
*/
public InputStream getInputStream() throws IOException { public InputStream getInputStream() throws IOException {
if (closed){ if (closed){
throw new IOException("Stream closed"); throw new IOException("Stream closed");
...@@ -27,6 +47,11 @@ public class CityGmlZipEntryFile implements AutoCloseable { ...@@ -27,6 +47,11 @@ public class CityGmlZipEntryFile implements AutoCloseable {
return zip.getInputStream(zipEntry); return zip.getInputStream(zipEntry);
} }
/**
* Gets an estimation of this file's filesize.
* @return filesize in bytes, -1L if unknown
* @throws IOException when this method is called after the file has been closed.
*/
public long getFileSize() throws IOException { public long getFileSize() throws IOException {
if (closed){ if (closed){
throw new IOException("Stream closed"); throw new IOException("Stream closed");
......
package de.hft.stuttgart.citydoctor2.zip; package de.hft.stuttgart.citydoctor2.zip;
/**
* Error types for {@link CityGmlZipEntry} objects.
*/
public enum ZipEntryErrorType { public enum ZipEntryErrorType {
INVALID_CITY_GML_FILE, EXCESSIVE_FILESIZE, IO_ERROR INVALID_CITY_GML_FILE, EXCESSIVE_FILESIZE, IO_ERROR
} }
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment