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 final char first = line.charAt(0);
073 if (Character.isLetter(first)) {
074
075 // new key
076
077 if (buffer.length() > 0) {
078 // flush value of previous key
079 set(key, buffer.toString());
080 buffer = new StringBuffer();
081 }
082
083
084 final int i = line.indexOf(':');
085
086 if (i < 0) {
087 throw new ParseException("Line misses ':' delimitter", linenr);
088 }
089
090 key = line.substring(0, i);
091 buffer.append(line.substring(i+1).trim());
092
093 continue;
094 }
095
096 // continuing old value
097 buffer.append('\n').append(line.substring(1));
098 }
099 br.close();
100
101 }
102
103 public void set( final String pKey, final String pValue ) {
104
105 if (resolver != null) {
106 try {
107 values.put(pKey, Utils.replaceVariables(resolver, pValue, "[[", "]]"));
108 return;
109 } catch (ParseException e) {
110 // FIXME maybe throw an Exception?
111 }
112 }
113
114 values.put(pKey, pValue);
115 }
116
117 public String get( final String pKey ) {
118 return (String)values.get(pKey);
119 }
120
121 public abstract String[] getMandatoryKeys();
122
123 public boolean isValid() {
124 return invalidKeys().size() == 0;
125 }
126
127 public Set invalidKeys() {
128 final Set invalid = new HashSet();
129
130 final String[] mk = getMandatoryKeys();
131 for (int i = 0; i < mk.length; i++) {
132 if (get(mk[i]) == null) {
133 invalid.add(mk[i]);
134 }
135 }
136
137 return invalid;
138 }
139
140 String toString( final String[] pKeys ) {
141 final StringBuffer s = new StringBuffer();
142 for (int i = 0; i < pKeys.length; i++) {
143 final String key = pKeys[i];
144 final String value = (String) values.get(key);
145 if (value != null) {
146 s.append(key).append(":");
147
148 try {
149 BufferedReader reader = new BufferedReader(new StringReader(value));
150 String line;
151 while ((line = reader.readLine()) != null) {
152 if (line.length() != 0 && !Character.isWhitespace(line.charAt(0))) {
153 s.append(' ');
154 }
155
156 s.append(line).append('\n');
157 }
158 } catch (IOException e) {
159 e.printStackTrace();
160 }
161 }
162 }
163 return s.toString();
164 }
165 }