001: /*
002: * MCS Media Computer Software Copyright (c) 2005 by MCS
003: * -------------------------------------- Created on 16.01.2004 by w.klaas
004: *
005: * Licensed under the Apache License, Version 2.0 (the "License"); you may not
006: * use this file except in compliance with the License. You may obtain a copy of
007: * the License at
008: *
009: * http://www.apache.org/licenses/LICENSE-2.0
010: *
011: * Unless required by applicable law or agreed to in writing, software
012: * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
013: * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
014: * License for the specific language governing permissions and limitations under
015: * the License.
016: */
017: package de.mcs.utils;
018:
019: import java.io.BufferedWriter;
020: import java.io.IOException;
021: import java.io.OutputStream;
022: import java.io.OutputStreamWriter;
023: import java.util.ArrayList;
024: import java.util.Comparator;
025: import java.util.Date;
026: import java.util.Iterator;
027: import java.util.Properties;
028: import java.util.SortedSet;
029: import java.util.TreeSet;
030:
031: /**
032: * Some helper functions for properties like getting all keys with a regex.
033: *
034: * @author w.klaas
035: *
036: */
037: public class PropertiesHelper extends Properties {
038:
039: /**
040: *
041: */
042: private static final long serialVersionUID = -3239128704806211452L;
043:
044: /**
045: * Searching for all Keys with the regex string.
046: *
047: * @param regex
048: * regular expression for the keys to find
049: * @return String[] array with all found keys
050: */
051: public final String[] getKeys(final String regex) {
052: ArrayList<String> list = new ArrayList<String>();
053: for (Iterator iter = keySet().iterator(); iter.hasNext();) {
054: String key = (String) iter.next();
055: if (key.matches(regex)) {
056: list.add(key);
057: }
058: }
059: return (String[]) list.toArray(new String[0]);
060: }
061:
062: /**
063: * Extracting all properties into a new Propertie class with begin with the
064: * prefix keyPrefix.
065: *
066: * @param keyPrefix
067: * the prefix to use.
068: * @return Properties
069: */
070: public final Properties extractProperties(final String keyPrefix) {
071: Properties mediaProps = new Properties();
072: String[] mediaKeyNames = getKeys(keyPrefix + ".*");
073: for (int j = 0; j < mediaKeyNames.length; j++) {
074: String key = mediaKeyNames[j];
075: String value = getProperty(key);
076: key = key.substring(key.indexOf(keyPrefix + ".")
077: + (keyPrefix + ".").length());
078: mediaProps.setProperty(key, value);
079: }
080: return mediaProps;
081: }
082:
083: /**
084: * Storing a properties class in a Stream in sorted manner.
085: *
086: * @param out
087: * the output stream
088: * @param comments
089: * the comments header.
090: * @throws IOException
091: * if something goes wrong.
092: */
093: public final void storeSorted(final OutputStream out,
094: final String comments) throws IOException {
095:
096: BufferedWriter awriter;
097: awriter = new BufferedWriter(new OutputStreamWriter(out,
098: "8859_1"));
099: if (comments != null) {
100: writeln(awriter, "#" + comments);
101: }
102: writeln(awriter, "#" + new Date().toString());
103: SortedSet<Object> mySet = new TreeSet<Object>(
104: new Comparator<Object>() {
105:
106: public int compare(final Object o1, final Object o2) {
107: if ((o1 instanceof String)
108: && (o2 instanceof String)) {
109: String s1 = (String) o1;
110: String s2 = (String) o2;
111: return s1.compareTo(s2);
112: }
113: return 0;
114: }
115:
116: });
117: mySet.addAll(keySet());
118: for (Iterator iter = mySet.iterator(); iter.hasNext();) {
119: String key = (String) iter.next();
120: String val = (String) get(key);
121: key = saveConvert(key, true);
122:
123: /*
124: * No need to escape embedded and trailing spaces for value, hence
125: * pass false to flag.
126: */
127: val = saveConvert(val, false);
128: writeln(awriter, key + "=" + val);
129: }
130: awriter.flush();
131: }
132:
133: /**
134: * write aa string and a newLine after.
135: *
136: * @param bw
137: * where to write.
138: * @param s
139: * what to write.
140: * @throws IOException
141: * if something goes wrong.
142: */
143: private static void writeln(final BufferedWriter bw, final String s)
144: throws IOException {
145: bw.write(s);
146: bw.newLine();
147: }
148:
149: /**
150: * Converts unicodes to encoded \uxxxx and escapes special characters
151: * with a preceding slash.
152: *
153: * @param theString
154: * the string to convert.
155: * @param escapeSpace
156: * escape the spaces too.
157: * @return the converted String.
158: */
159: private String saveConvert(final String theString,
160: final boolean escapeSpace) {
161: int len = theString.length();
162: int bufLen = len * 2;
163: if (bufLen < 0) {
164: bufLen = Integer.MAX_VALUE;
165: }
166: StringBuffer outBuffer = new StringBuffer(bufLen);
167:
168: for (int x = 0; x < len; x++) {
169: char aChar = theString.charAt(x);
170: // Handle common case first, selecting largest block that
171: // avoids the specials below
172: if ((aChar > 61) && (aChar < 127)) {
173: if (aChar == '\\') {
174: outBuffer.append('\\');
175: outBuffer.append('\\');
176: continue;
177: }
178: outBuffer.append(aChar);
179: continue;
180: }
181: switch (aChar) {
182: case ' ':
183: if (x == 0 || escapeSpace) {
184: outBuffer.append('\\');
185: }
186: outBuffer.append(' ');
187: break;
188: case '\t':
189: outBuffer.append('\\');
190: outBuffer.append('t');
191: break;
192: case '\n':
193: outBuffer.append('\\');
194: outBuffer.append('n');
195: break;
196: case '\r':
197: outBuffer.append('\\');
198: outBuffer.append('r');
199: break;
200: case '\f':
201: outBuffer.append('\\');
202: outBuffer.append('f');
203: break;
204: case '=': // Fall through
205: case ':': // Fall through
206: case '#': // Fall through
207: case '!':
208: outBuffer.append('\\');
209: outBuffer.append(aChar);
210: break;
211: default:
212: if ((aChar < 0x0020) || (aChar > 0x007e)) {
213: outBuffer.append('\\');
214: outBuffer.append('u');
215: outBuffer.append(toHex((aChar >> 12) & 0xF));
216: outBuffer.append(toHex((aChar >> 8) & 0xF));
217: outBuffer.append(toHex((aChar >> 4) & 0xF));
218: outBuffer.append(toHex(aChar & 0xF));
219: } else {
220: outBuffer.append(aChar);
221: }
222: }
223: }
224: return outBuffer.toString();
225: }
226:
227: /**
228: * Convert a nibble to a hex character.
229: *
230: * @param nibble
231: * the nibble to convert.
232: * @return char
233: */
234: private static char toHex(final int nibble) {
235: return HEXDIGIT[(nibble & 0xF)];
236: }
237:
238: /** A table of hex digits. */
239: private static final char[] HEXDIGIT = { '0', '1', '2', '3', '4',
240: '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' };
241:
242: }
|