001 /*
002 * Copyright 2005 The Apache Software Foundation.
003 *
004 * Licensed under the Apache License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 * http://www.apache.org/licenses/LICENSE-2.0
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 */
016 package org.vafer.jdeb.descriptors;
017
018 import java.io.BufferedReader;
019 import java.io.IOException;
020 import java.io.InputStream;
021 import java.io.InputStreamReader;
022 import java.io.StringReader;
023 import java.text.ParseException;
024 import java.util.HashMap;
025 import java.util.HashSet;
026 import java.util.Map;
027 import java.util.Set;
028
029 import org.vafer.jdeb.utils.Utils;
030 import org.vafer.jdeb.utils.VariableResolver;
031
032 /**
033 * A descriptor holds the usual key value pairs.
034 *
035 * @see <a href="http://www.debian.org/doc/debian-policy/ch-controlfields.html">Debian Policy Manual - Control files and their fields</a>
036 *
037 * @author Torsten Curdt <tcurdt@vafer.org>
038 */
039 public abstract class AbstractDescriptor {
040
041 private final Map values = new HashMap();
042 private final VariableResolver resolver;
043
044 public AbstractDescriptor( final VariableResolver pResolver ) {
045 resolver = pResolver;
046 }
047
048 public AbstractDescriptor( final AbstractDescriptor pDescriptor ) {
049 values.putAll(pDescriptor.values);
050 resolver = pDescriptor.resolver;
051 }
052
053 protected void parse( final InputStream pInput ) throws IOException, ParseException {
054 final BufferedReader br = new BufferedReader(new InputStreamReader(pInput));
055 StringBuffer buffer = new StringBuffer();
056 String key = null;
057 int linenr = 0;
058 while(true) {
059 final String line = br.readLine();
060
061 if (line == null) {
062 if (buffer.length() > 0) {
063 // flush value of previous key
064 set(key, buffer.toString());
065 buffer = null;
066 }
067 break;
068 }
069
070 linenr++;
071
072 if (line.length() == 0) {
073 throw new ParseException("Empty line", linenr);
074 }
075
076 final char first = line.charAt(0);
077 if (Character.isLetter(first)) {
078
079 // new key
080
081 if (buffer.length() > 0) {
082 // flush value of previous key
083 set(key, buffer.toString());
084 buffer = new StringBuffer();
085 }
086
087
088 final int i = line.indexOf(':');
089
090 if (i < 0) {
091 throw new ParseException("Line misses ':' delimitter", linenr);
092 }
093
094 key = line.substring(0, i);
095 buffer.append(line.substring(i+1).trim());
096
097 continue;
098 }
099
100 // continuing old value
101 buffer.append('\n').append(line.substring(1));
102 }
103 br.close();
104
105 }
106
107 public void set( final String pKey, final String pValue ) {
108
109 if (resolver != null) {
110 try {
111 values.put(pKey, Utils.replaceVariables(resolver, pValue, "[[", "]]"));
112 return;
113 } catch (ParseException e) {
114 // FIXME maybe throw an Exception?
115 }
116 }
117
118 values.put(pKey, pValue);
119 }
120
121 public String get( final String pKey ) {
122 return (String)values.get(pKey);
123 }
124
125 public abstract String[] getMandatoryKeys();
126
127 public boolean isValid() {
128 return invalidKeys().size() == 0;
129 }
130
131 public Set invalidKeys() {
132 final Set invalid = new HashSet();
133
134 final String[] mk = getMandatoryKeys();
135 for (int i = 0; i < mk.length; i++) {
136 if (get(mk[i]) == null) {
137 invalid.add(mk[i]);
138 }
139 }
140
141 return invalid;
142 }
143
144 String toString( final String[] pKeys ) {
145 final StringBuffer s = new StringBuffer();
146 for (int i = 0; i < pKeys.length; i++) {
147 final String key = pKeys[i];
148 final String value = (String) values.get(key);
149 if (value != null) {
150 s.append(key).append(":");
151
152 try {
153 BufferedReader reader = new BufferedReader(new StringReader(value));
154 String line;
155 while ((line = reader.readLine()) != null) {
156 if (line.length() != 0 && !Character.isWhitespace(line.charAt(0))) {
157 s.append(' ');
158 }
159
160 s.append(line).append('\n');
161 }
162 } catch (IOException e) {
163 e.printStackTrace();
164 }
165 }
166 }
167 return s.toString();
168 }
169 }