summaryrefslogtreecommitdiffstats
path: root/javatoscachecker/checker/src/main/java/org/onap/tosca/checker/CSARRepository.java
diff options
context:
space:
mode:
Diffstat (limited to 'javatoscachecker/checker/src/main/java/org/onap/tosca/checker/CSARRepository.java')
-rw-r--r--javatoscachecker/checker/src/main/java/org/onap/tosca/checker/CSARRepository.java282
1 files changed, 282 insertions, 0 deletions
diff --git a/javatoscachecker/checker/src/main/java/org/onap/tosca/checker/CSARRepository.java b/javatoscachecker/checker/src/main/java/org/onap/tosca/checker/CSARRepository.java
new file mode 100644
index 0000000..6375185
--- /dev/null
+++ b/javatoscachecker/checker/src/main/java/org/onap/tosca/checker/CSARRepository.java
@@ -0,0 +1,282 @@
+/*
+ * Copyright (c) 2017 <AT&T>. All rights reserved.
+ * ===================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed
+ * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for
+ * the specific language governing permissions and limitations under the License.
+ */
+package org.onap.tosca.checker;
+
+import java.io.IOException;
+import java.io.UnsupportedEncodingException;
+import java.io.Reader;
+import java.io.StringReader;
+import java.io.InputStream;
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.InputStreamReader;
+import java.io.BufferedReader;
+
+import java.net.URI;
+import java.net.URL;
+import java.net.MalformedURLException;
+
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+import java.util.Map;
+import java.util.HashMap;
+import java.util.Properties;
+import java.util.Collections;
+
+import java.util.zip.ZipInputStream;
+import java.util.zip.ZipEntry;
+
+import java.util.function.BiFunction;
+
+import org.apache.commons.io.IOUtils;
+
+/**
+ * Handles targets located within the same CSAR file.
+ * This is where the knowledge about the structure of a CSAR file should be placed.
+ * TOSCA 1.0 CSAR archive compliant.
+ */
+public class CSARRepository extends Repository {
+
+
+ private String metaEntryName = "TOSCA-Metadata/TOSCA.meta";
+
+ private byte[] data;
+ private Properties meta = new Properties();
+ private Map<URI, Target> entries = null;
+
+ public CSARRepository(String theName, URI theRoot) throws IOException {
+ super(theName, theRoot);
+ load();
+ }
+
+ private void load() throws IOException {
+ InputStream is = null;
+ try {
+ is = this.getRoot().toURL().openStream();
+ this.data = IOUtils.toByteArray(is);
+ }
+ finally {
+ if (is != null) {
+ try {
+ is.close();
+ }
+ catch(IOException iox) {}
+ }
+ }
+ }
+
+ //one should read the meta-inf/MANIFEST.MF file before deciding that a file is text
+ private Object processData(BiFunction<ZipEntry,InputStream,Object> theProcessor) {
+
+ ZipInputStream archiveInputStream = new ZipInputStream(new ByteArrayInputStream(this.data));
+ Object result = null;
+ try {
+ ZipEntry archiveEntry = null;
+ while ((archiveEntry = archiveInputStream.getNextEntry()) != null) {
+ result = theProcessor.apply(archiveEntry, archiveInputStream);
+ if (null != result)
+ return result;
+ archiveInputStream.closeEntry();
+ }
+ }
+ catch (IOException iox) {
+ log.log(Level.WARNING, "Failed to read archive", iox);
+ }
+ finally {
+ try {
+ archiveInputStream.close();
+ }
+ catch (IOException iox) {
+ }
+ }
+ return result;
+ }
+
+ /* this will be useful when processing new style meta information .. */
+ private Object processMeta() {
+ return
+ processData( (entry,stream) -> {
+ if (!entry.getName().equals(this.metaEntryName))
+ return null;
+
+ return readMeta(stream);
+ });
+ }
+
+ private Boolean readMeta(InputStream theStream) {
+ BufferedReader reader = null;
+ try {
+ reader = new BufferedReader(new InputStreamReader(theStream, "UTF-8"));
+ this.meta.load(reader);
+ return Boolean.TRUE;
+ }
+ catch(IOException iox) {
+ log.log(Level.WARNING, "Failed to read archive meta entry", iox);
+ return Boolean.FALSE;
+ }
+ finally {
+ /*
+ if (reader != null) {
+ try {
+ reader.close();
+ }
+ catch (IOException iox) {
+ }
+ }
+ */
+ //!!Do not close as it is used with processData which does the entry close itself
+ }
+ }
+
+ /*
+ private Boolean readMeta() {
+ BufferedReader reader = null;
+ try {
+ reader = new BufferedReader(new InputStreamReader(stream, "UTF-8"));
+ String line = null;
+ while ((line = reader.readLine()) != null) {
+ //TODO:
+ }
+ return Boolean.TRUE;
+ }
+ catch (IOException iox) {
+ log.log(Level.WARNING, "Failed to read archive meta entry", iox);
+ return Boolean.FALSE;
+ }
+ finally {
+ if (reader != null) {
+ try {
+ reader.close();
+ }
+ catch (IOException iox) {
+ }
+ }
+ //!!Do not close as it is used with processData which does the entry close itself
+ }
+ }
+ */
+
+ private Map<URI,Target> entries() {
+ if (this.entries == null) {
+ this.entries = new HashMap<URI, Target>();
+ processData( (entry,stream) -> {
+ URI entryURI = this.rootURI.resolve(entry.getName());
+ this.entries.put(entryURI, new CsarTarget(entry.getName(), entryURI));
+
+ if (entry.getName().equals(this.metaEntryName))
+ readMeta(stream);
+
+ return null;
+ });
+ }
+ return this.entries;
+ }
+
+ public Target mainTarget() {
+ return entries().get(rootURI.resolve(this.meta.getProperty("Entry-Definitions")));
+ }
+
+ public Iterable<Target> targets() {
+ return entries().values();
+ }
+
+ /** */
+ public Target resolve(URI theURI) {
+ return entries().get(theURI);
+ }
+
+ public TargetLocator getTargetLocator() {
+ return new CSARTargetLocator();
+ }
+
+ /**
+ */
+ private class CSARTargetLocator implements TargetLocator {
+
+ /** */
+ public boolean addSearchPath(URI theURI) {
+ return false;
+ }
+
+ /** */
+ public boolean addSearchPath(String thePath) {
+ return false;
+ }
+
+ /** */
+ public Iterable<URI> searchPaths() {
+ return Collections.singleton(CSARRepository.this.rootURI);
+ }
+
+ /** */
+ public Target resolve(String theName) {
+ Target t = entries().get(CSARRepository.this.rootURI.resolve(theName));
+ if (t == null) {
+ //fallback: check relative to the main target folder
+ t = entries().get(CSARRepository.this.mainTarget().getLocation().resolve(theName));
+ }
+ return t;
+ }
+ }
+
+ /** */
+ private class CsarTarget extends Target {
+
+ private String content;
+
+ private CsarTarget(String theName, URI theUri) {
+ super(theName, theUri);
+ }
+
+ private String content() {
+ if (this.content == null) {
+ this.content = (String)processData( (entry,stream) -> {
+ //go over the entries and find the one with a matching name
+ ByteArrayOutputStream out = null;
+ if (entry.getName().equals(getName())) {
+ byte[] buffer = new byte[4096];
+ int len = 0;
+ out = new ByteArrayOutputStream();
+ try {
+ while ((len = stream.read(buffer)) > 0) {
+ out.write(buffer, 0, len);
+ }
+ log.info(entry.getName() + ": " + out.toString("UTF-8"));
+ }
+ catch (IOException iox) {
+ log.warning("Failed to read entry data: " + iox);
+ return out = null;
+ }
+ }
+ //!!Do not close as it is used with processData which does the entry close itself
+
+ try {
+ return (out != null) ? out.toString("UTF-8") : null;
+ }
+ catch (UnsupportedEncodingException uex) {
+ log.warning("Failed to process entry data as string: " + uex);
+ return "";
+ }
+ });
+ }
+ return this.content;
+ }
+
+ public Reader open() throws IOException {
+ return new StringReader(content());
+ }
+ }
+
+}
+