View Javadoc

1   //Copyright 2006-2007, by the California Institute of Technology.
2   //ALL RIGHTS RESERVED. United States Government Sponsorship acknowledged.
3   //Any commercial use must be negotiated with the Office of Technology Transfer
4   //at the California Institute of Technology.
5   //
6   //This software is subject to U. S. export control laws and regulations
7   //(22 C.F.R. 120-130 and 15 C.F.R. 730-774). To the extent that the software
8   //is subject to U.S. export control laws and regulations, the recipient has
9   //the responsibility to obtain export licenses or other export authority as
10  //may be required before exporting such information to foreign countries or
11  //providing access to foreign nationals.
12  
13  package gov.nasa.pds.ltdt.testLabel;
14  
15  import gov.nasa.pds.ltdt.gui.util.Utility;
16  import gov.nasa.pds.tools.dict.Dictionary;
17  import gov.nasa.pds.tools.dict.ElementDefinition;
18  import gov.nasa.pds.tools.dict.parser.UnknownDefinitionException;
19  import gov.nasa.pds.tools.dict.type.InvalidTypeException;
20  import gov.nasa.pds.tools.dict.type.UnsupportedTypeException;
21  
22  import java.io.BufferedReader;
23  import java.io.IOException;
24  import java.io.InputStream;
25  import java.io.InputStreamReader;
26  import java.io.OutputStream;
27  import java.util.Iterator;
28  import java.util.LinkedHashSet;
29  import java.util.Set;
30  import java.util.regex.Matcher;
31  import java.util.regex.Pattern;
32  
33  /***
34   * This class will generate a test label based on a compliant, label template.
35   * 
36   * Any variables found in the template will be replaced by an appropriate
37   * test value, to be used for the purposes of checking that the label template
38   * is compliant according to PDS standards.
39   * 
40   * @author mcayanan
41   *
42   */
43  public class TestLabelGenerator {
44  	private final static String KEYWORD_VALUE_PATTERN = "(//s*[//w:]+//s*)={1}.*";
45  	private final static String POINTER_PATTERN = "(//s*//^{1}[//w:]+//s*)={1}.*";
46  	private final static String VARIABLE_PATTERN = "(//$//{[//w:]+//})";
47  	private ElementDefinition definition;
48  	private Pattern kwdValuePattern;
49  	private Pattern variablePattern;
50  	private Variable variable;
51  	private String keyword;
52  	
53  	/***
54  	 * Constructor
55  	 * 
56  	 */
57  	public TestLabelGenerator() {
58  		variable = new Variable();
59  		kwdValuePattern = Pattern.compile(KEYWORD_VALUE_PATTERN);
60  		variablePattern = Pattern.compile(VARIABLE_PATTERN);
61  		definition = null;
62  		keyword = null;
63  	}
64  	
65  	/***
66  	 * Writes the test label to a given output stream.
67  	 * 
68  	 * @param labelTemplate A stream representation of a PDS label template.
69  	 * @param dictionary A dictionary
70  	 * @param out An output stream where the test label will be stored.
71  	 * 
72  	 * @throws IOException
73  	 * @throws InvalidTypeException
74  	 * @throws UnsupportedTypeException
75  	 * @throws UnknownDefinitionException If there were missing element definitions
76  	 * for keywords that contained a variable.
77  	 */
78  	public void createTestLabel(InputStream labelTemplate, 
79  			                        Dictionary dictionary, OutputStream out)
80                   	                        throws IOException,
81  	                                               InvalidTypeException,
82  	                                               UnsupportedTypeException, 
83  	                                               UnknownDefinitionException {	
84  		BufferedReader reader = new BufferedReader(new InputStreamReader(labelTemplate));
85  		Dictionary psdd = dictionary;
86  		Set missingDefinitions = new LinkedHashSet();
87  		try {
88  			for(String line = null; (line = reader.readLine()) != null;) {
89  				//If a keyword-value statement is found, find the element
90  				//definition.
91  				Matcher matcher = kwdValuePattern.matcher(line);
92  				if(matcher.matches()) {
93  					keyword = matcher.group(1).trim();
94  					definition = psdd.getElementDefinition(keyword);
95  				}
96  				//Find a variable in the string. If it is present, then 
97  				//perform variable substitution.
98  				Matcher vm = variablePattern.matcher(line);
99  				if(vm.find()) {
100 					try {
101 						line = replaceVariables(line);
102 					}catch (UnknownDefinitionException ex) {
103 						missingDefinitions.add(keyword);
104 					}
105 				}
106 				line = Utility.addCRLF(line);
107 				out.write(line.getBytes());
108 			}
109 		} finally {
110 			reader.close();
111 			out.close();
112 		}
113 		//Throw an exception if there were missing element definitions for keywords
114 		//that contained a variable.
115 		if(!missingDefinitions.isEmpty()) {
116 			String message = "";
117 			for(Iterator i=missingDefinitions.iterator(); i.hasNext();) {
118 				message = message + i.next().toString() + "\n";
119 			}
120 			throw new UnknownDefinitionException(message);
121 		}
122 	}
123 	
124 	/***
125 	 * Replaces variables with an appropriate test value.
126 	 * 
127 	 * @param line A line in the label template, possibly containing variables.
128 	 * @return
129 	 * @throws InvalidTypeException
130 	 * @throws UnsupportedTypeException
131 	 * @throws UnknownDefinitionException 
132 	 */
133 	private String replaceVariables(String line) throws InvalidTypeException,
134 	                    UnsupportedTypeException, UnknownDefinitionException {
135 		//Check to see if the given line is a pointer statement
136 		if(line.matches(POINTER_PATTERN))
137 			line = variable.doPointerSubstitution(line);
138 		else {
139 			try {
140 				line = variable.doSubstitution(line, definition);
141 			} catch (UnknownDefinitionException ex) {
142 				throw new UnknownDefinitionException("Missing definition for " + keyword);
143 			}
144 		}
145 		return line;
146 	}
147 }