001: /*
002: * Project: LIUS Package: de.teamskill.util
003: *
004: * Copyright (c) 2004 by Jens Fendler <jf@teamskill.de>
005: *
006: * This program is a free software; you can redistribute it and/or modify it
007: * under the terms of the GNU General Public License as published by the Free
008: * Software Foundation; either version 2 of the License, or (at your option) any
009: * later version. This program is distributed in the hope that it will be
010: * useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
011: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
012: * Public License for more details. You should have received a copy of the GNU
013: * General Public License along with this program; if not, write to the Free
014: * Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
015: * USA
016: */
017:
018: package de.teamskill.util;
019:
020: import java.io.Serializable;
021: import java.util.List;
022: import java.util.StringTokenizer;
023: import java.util.Vector;
024:
025: /**
026: * Class: VCard <br>
027: *
028: * This class represents a single VCard which is either constructed or read from
029: * a string that must begin with 'BEGIN:VCARD' and end with 'END:VCARD'. All
030: * fields - including possible extensions (e.g. from mozilla) - will be read.
031: * This class overrides the toString() method for outputting a constructed the
032: * VCard entry.
033: *
034: * Changelog:
035: * <ul>
036: * <li>02.06.2005: Initial implementation (jf)</li>
037: * <li>03.06.2005: changes from java.lang.String.contains() to indexOf() for
038: * JDK 1.4 compatibility (jf)</li>
039: * </ul>
040: *
041: * @author <a href="mailto:jf@teamskill.de">Jens Fendler </a>
042: */
043: public class VCard implements Serializable {
044:
045: public static String PATTERN_BEGIN = "BEGIN:VCARD";
046:
047: public static String PATTERN_END = "END:VCARD";
048:
049: private static String lineSep = System
050: .getProperty("line.separator");
051:
052: private List cardElements = new Vector();
053:
054: /**
055: * container for a single VCard element/line (such as
056: * 'EMAIL;INTERNET:me@home.org')
057: */
058: class VCElement {
059:
060: /**
061: * Construct a single VCard element
062: *
063: * @param key:
064: * the element's key
065: * @param type:
066: * the element's type (or null if n/a)
067: * @param data:
068: * user data
069: */
070: public VCElement(String key, String type, String data) {
071: this .key = key;
072: this .type = type;
073: this .data = data;
074: }
075:
076: /**
077: * <code>key</code>: the element's key (e.g. 'EMAIL')
078: */
079: String key;
080:
081: /**
082: * <code>type</code>: the element's type (might be null) (e.g.
083: * 'WORK')
084: */
085: String type;
086:
087: /**
088: * <code>data</code>: the element's data (e.g. 'me@home.org')
089: */
090: String data;
091:
092: public String toString() {
093: return "[VCElement key=" + key + ", type=" + type
094: + ", data=" + data + "]";
095: }
096: }
097:
098: public VCard() {
099: }
100:
101: public VCard(String cardString) {
102: // check if we have a valid VCard string
103: if (cardString.startsWith(PATTERN_BEGIN)
104: && cardString.endsWith(PATTERN_END)) {
105:
106: // seperate the lines
107: StringTokenizer lt = new StringTokenizer(cardString,
108: lineSep);
109: while (lt.hasMoreTokens()) {
110: String line = lt.nextToken();
111:
112: // do we have a key/value-pair?
113: int metaSep = line.indexOf(':');
114: if ((metaSep != -1)
115: && (line.indexOf(PATTERN_BEGIN) == -1)
116: && (line.indexOf(PATTERN_END) == -1)) {
117: // seperate metadata from content
118: String meta = line.substring(0, metaSep);
119: String content = line.substring(metaSep + 1, line
120: .length());
121:
122: // check to see if we can add this VCard element..
123: if (keyAllowed(meta)) {
124: // do we have a subclassed field?
125: int i = meta.indexOf(';');
126: VCElement e = null;
127: if (i != -1) {
128: // subclassed field found
129: e = new VCElement(meta.substring(0, i),
130: meta.substring(i, meta.length()),
131: content);
132:
133: } else {
134: // simple field found
135: e = new VCElement(meta, null, content);
136:
137: }
138: // add the new element to the list of available elements
139: cardElements.add(e);
140: }
141: }
142: }
143: } else
144: throw new IllegalArgumentException(
145: "Unsupported VCard format. Must " + PATTERN_BEGIN
146: + " ... " + PATTERN_END + "'");
147: }
148:
149: /**
150: * keyAllowed this method should be used to force exclusion of certain
151: * fields (e.g. binary content)
152: *
153: * @param meta
154: * the meta (key/type) part of the element in question
155: * @return true, if this field should be added as a VCElement, otherwise
156: * false
157: */
158: private boolean keyAllowed(String meta) {
159: return !meta.startsWith("PHOTO");
160: }
161:
162: /**
163: * getCardElements get all available elements
164: *
165: * @return List of VCard.VCElement
166: */
167: public List getCardElements() {
168: return cardElements;
169: }
170:
171: /**
172: * setCardElements set the card elements
173: *
174: * @param cardElements:
175: * List of VCard.VCElement
176: */
177: public void setCardElements(List cardElements) {
178: this .cardElements = cardElements;
179: }
180:
181: /**
182: * getElement iterates over all available card elements and returns the data
183: * parts for all matching key elements <br/>(note: use
184: * getElement(String,String) for additional type lookup)
185: *
186: * @param key:
187: * the key to search for (e.g. 'EMAIL')
188: * @return the first matching element or null if no match was found
189: */
190: public String getElement(String key) {
191: StringBuffer sb = new StringBuffer();
192: for (int i = 0; i < cardElements.size(); i++) {
193: VCElement e = (VCElement) cardElements.get(i);
194: if (key.equals(e.key))
195: sb.append(e.data).append(", ");
196: }
197: String ret = sb.toString();
198: // remove trailing ", "
199: if (ret.length() > 2)
200: return ret.substring(0, ret.length() - 2);
201: else
202: return null;
203: }
204:
205: /**
206: * getElement iterates over all available card elements and returns the data
207: * parts for all matching key elements <br/>(note: use
208: * getElement(String,String) for additional type lookup)
209: *
210: * @param key:
211: * the key to search for (e.g. 'EMAIL')
212: * @param type:
213: * the type of the key to search for (e.g. 'WORK')
214: * @return the first matching element or null if no match was found
215: */
216: public String getElement(String key, String type) {
217: StringBuffer sb = new StringBuffer();
218: for (int i = 0; i < cardElements.size(); i++) {
219: VCElement e = (VCElement) cardElements.get(i);
220: if (key.equals(e.key) && type.equals(e.type))
221: sb.append(e.data).append(", ");
222: }
223: String ret = sb.toString();
224: // remove trailing ", "
225: if (ret.length() > 2)
226: return ret.substring(0, ret.length() - 2);
227: else
228: return null;
229: }
230:
231: /**
232: * @see java.lang.Object#toString()
233: */
234: public String toString() {
235: StringBuffer sb = new StringBuffer(PATTERN_BEGIN)
236: .append(lineSep);
237: for (int i = 0; i < cardElements.size(); i++) {
238: VCElement e = (VCElement) cardElements.get(i);
239: sb.append(e.key);
240: if (e.type != null)
241: sb.append(';').append(e.type);
242: sb.append(':').append(e.data).append(lineSep);
243: }
244: sb.append(PATTERN_END);
245: return sb.toString();
246: }
247:
248: }
|