1 /*******************************************************************************
2 * Copyright (c) 2013 Rene Trefft.
3 * All rights reserved. This program and the accompanying materials
4 * are made available under the terms of the Eclipse Public License v1.0
5 * and the Apache License 2.0 which both accompany this distribution,
6 * and are available at http://www.eclipse.org/legal/epl-v10.html
7 * and http://www.apache.org/licenses/LICENSE-2.0
10 * Rene Trefft - initial API and implementation and/or initial documentation
11 *******************************************************************************/
12 package org.eclipse.winery.model.csar.toscametafile;
14 import java.io.FileNotFoundException;
15 import java.io.FileReader;
16 import java.io.IOException;
17 import java.nio.file.Path;
18 import java.util.List;
21 import org.slf4j.Logger;
22 import org.slf4j.LoggerFactory;
24 import com.springsource.util.parser.manifest.ManifestContents;
25 import com.springsource.util.parser.manifest.ManifestParser;
26 import com.springsource.util.parser.manifest.ManifestProblem;
27 import com.springsource.util.parser.manifest.RecoveringManifestParser;
30 * Parses and validates a TOSCA meta file.<br />
32 * Copyright 2013 IAAS University of Stuttgart <br />
35 * @author Rene Trefft - rene.trefft@developers.opentosca.org
38 public class TOSCAMetaFileParser {
40 final private static Logger LOG = LoggerFactory.getLogger(TOSCAMetaFileParser.class);
44 * Parses and validates the <code>toscaMetaFile</code>.<br />
47 * @param toscaMetaFile to process
48 * @return <code>TOSCAMetaFile</code> that gives access to the content of
49 * the TOSCA meta file. If the given file doesn't exist or is
50 * invalid <code>null</code>.
52 public TOSCAMetaFile parse(Path toscaMetaFile) {
54 // counts the errors during parsing
57 FileReader reader = null;
58 ManifestParser parser = null;
59 ManifestContents manifestContent = null;
60 TOSCAMetaFile toscaMetaFileContent = null;
64 parser = new RecoveringManifestParser();
65 reader = new FileReader(toscaMetaFile.toFile());
66 TOSCAMetaFileParser.LOG.debug("Parsing TOSCA meta file \"{}\"...", toscaMetaFile.getFileName().toString());
67 manifestContent = parser.parse(reader);
70 for (ManifestProblem problem : parser.getProblems()) {
71 this.logManifestProblem(problem);
75 numErrors += this.validateBlock0(manifestContent);
76 numErrors += this.validateFileBlocks(manifestContent);
79 TOSCAMetaFileParser.LOG.debug("Parsing TOSCA meta file \"{}\" completed without errors. TOSCA meta file is valid.", toscaMetaFile.getFileName().toString());
80 toscaMetaFileContent = new TOSCAMetaFile(manifestContent);
82 TOSCAMetaFileParser.LOG.error("Parsing TOSCA meta file \"{}\" failed - {} error(s) occured. TOSCA meta file is invalid.", toscaMetaFile.getFileName().toString(), numErrors);
85 } catch (FileNotFoundException exc) {
86 TOSCAMetaFileParser.LOG.error("\"{}\" doesn't exist or is not a file.", toscaMetaFile, exc);
87 } catch (IOException exc) {
88 TOSCAMetaFileParser.LOG.error("An IO Exception occured.", exc);
93 } catch (IOException exc) {
94 TOSCAMetaFileParser.LOG.warn("An IOException occured.", exc);
99 return toscaMetaFileContent;
104 * Validates block 0 of the TOSCA meta file.<br />
106 * Required attributes in block 0:
108 * <li><code>TOSCA-Meta-Version</code> (value must be <code>1.0</code>)</li>
109 * <li><code>CSAR-Version</code> (value must be <code>1.0</code>)</li>
110 * <li><code>Created-By</code></li>
112 * Optional attributes in block 0:
114 * <li><code>Entry-Definitions</code></li>
115 * <li><code>Description</code></li>
116 * <li><code>Topology</code></li>
119 * Further, arbitrary attributes are also allowed.<br />
122 * @param mf to validate
123 * @return Number of errors occurred during validation.
125 private int validateBlock0(ManifestContents mf) {
129 String metaFileVersion = null;
130 String csarVersion = null;
131 String createdBy = null;
132 String entryDefinitions = null;
133 String description = null;
134 String topology = null;
136 Map<String, String> mainAttr = mf.getMainAttributes();
138 metaFileVersion = mainAttr.get(TOSCAMetaFileAttributes.TOSCA_META_VERSION);
140 if (metaFileVersion == null) {
141 this.logAttrMissing(TOSCAMetaFileAttributes.TOSCA_META_VERSION, 0);
143 } else if (!(metaFileVersion = metaFileVersion.trim()).equals(TOSCAMetaFileAttributes.TOSCA_META_VERSION_VALUE)) {
144 this.logAttrWrongVal(TOSCAMetaFileAttributes.TOSCA_META_VERSION, 0, TOSCAMetaFileAttributes.TOSCA_META_VERSION_VALUE);
148 csarVersion = mainAttr.get(TOSCAMetaFileAttributes.CSAR_VERSION);
150 if (csarVersion == null) {
151 this.logAttrMissing(TOSCAMetaFileAttributes.CSAR_VERSION, 0);
153 } else if (!(csarVersion = csarVersion.trim()).equals(TOSCAMetaFileAttributes.TOSCA_META_VERSION_VALUE)) {
154 this.logAttrWrongVal(TOSCAMetaFileAttributes.CSAR_VERSION, 0, TOSCAMetaFileAttributes.CSAR_VERSION_VALUE);
158 createdBy = mainAttr.get(TOSCAMetaFileAttributes.CREATED_BY);
160 if (createdBy == null) {
161 this.logAttrMissing(TOSCAMetaFileAttributes.CREATED_BY, 0);
163 } else if ((createdBy = createdBy.trim()).isEmpty()) {
164 this.logAttrValEmpty(TOSCAMetaFileAttributes.CREATED_BY, 0);
168 entryDefinitions = mainAttr.get(TOSCAMetaFileAttributes.ENTRY_DEFINITIONS);
170 if ((entryDefinitions != null) && entryDefinitions.trim().isEmpty()) {
171 this.logAttrValEmpty(TOSCAMetaFileAttributes.ENTRY_DEFINITIONS, 0);
175 description = mainAttr.get(TOSCAMetaFileAttributes.DESCRIPTION);
177 if ((description != null) && description.trim().isEmpty()) {
178 this.logAttrValEmpty(TOSCAMetaFileAttributes.DESCRIPTION, 0);
182 topology = mainAttr.get(TOSCAMetaFileAttributes.TOPOLOGY);
184 if ((topology != null) && topology.trim().isEmpty()) {
185 this.logAttrValEmpty(TOSCAMetaFileAttributes.TOPOLOGY, 0);
194 * Validates the file blocks (block 1 to last block) of the TOSCA meta file.<br />
196 * Each file block has the following required attributes:
198 * <li><code>Name</code></li>
199 * <li><code>Content-Type</code> (will be checked for correct syntax)</li>
202 * Further, arbitrary attributes are also allowed in a file block.<br />
205 * @param mf to validate.
206 * @return Number of errors occurred during validation.
208 private int validateFileBlocks(ManifestContents mf) {
215 List<String> names = mf.getSectionNames();
217 for (String name : names) {
221 if ((name != null) && name.trim().isEmpty()) {
222 this.logAttrValEmpty(name, blockNr);
226 Map<String, String> attr = mf.getAttributesForSection(name);
227 contentType = attr.get(TOSCAMetaFileAttributes.CONTENT_TYPE);
229 if (contentType == null) {
230 this.logAttrMissing(TOSCAMetaFileAttributes.CONTENT_TYPE, blockNr);
232 } else if (!contentType.trim().matches("^[-\\w\\+\\.]+/[-\\w\\+\\.]+$")) {
233 this.logAttrWrongVal(TOSCAMetaFileAttributes.CONTENT_TYPE, blockNr);
244 * Logs that attribute <code>attributeName</code> in block
245 * <code>blockNr</code> is missing.
247 * @param attributeName
250 private void logAttrMissing(String attributeName, int blockNr) {
251 TOSCAMetaFileParser.LOG.warn("Required attribute {} in block {} is missing.", attributeName, blockNr);
255 * Logs that attribute <code>attributeName</code> in block
256 * <code>blockNr</code> has an invalid value. Correct is
257 * <code>correctValue</code>.
259 * @param attributeName
261 * @param correctValue
263 private void logAttrWrongVal(String attributeName, int blockNr, String correctValue) {
264 TOSCAMetaFileParser.LOG.warn("Attribute {} in block {} has an invalid value. Must be {}.", attributeName, blockNr, correctValue);
268 * Logs that attribute <code>attributeName</code> in block
269 * <code>blockNr</code> has an invalid value.
271 * @param attributeName
274 private void logAttrWrongVal(String attributeName, int blockNr) {
275 TOSCAMetaFileParser.LOG.warn("Attribute {} in block {} has an invalid value.", attributeName, blockNr);
279 * Logs that attribute <code>attributeName</code> in block
280 * <code>blockNr</code> has an empty value.
282 * @param attributeName
285 private void logAttrValEmpty(String attributeName, int blockNr) {
286 TOSCAMetaFileParser.LOG.warn("Attribute {} in block {} has a empty value.", attributeName, blockNr);
290 * Logs the ManifestProblem <code>problem</code>.
294 private void logManifestProblem(ManifestProblem problem) {
295 TOSCAMetaFileParser.LOG.warn(problem.toString());