Docjar: A Java Source and Docuemnt Enginecom.*    java.*    javax.*    org.*    all    new    plug-in

Quick Search    Search Deep

Source code: org/objectstyle/cayenne/wocompat/PropertyListSerialization.java


1   /* ====================================================================
2    * 
3    * The ObjectStyle Group Software License, Version 1.0 
4    *
5    * Copyright (c) 2002-2003 The ObjectStyle Group 
6    * and individual authors of the software.  All rights reserved.
7    *
8    * Redistribution and use in source and binary forms, with or without
9    * modification, are permitted provided that the following conditions
10   * are met:
11   *
12   * 1. Redistributions of source code must retain the above copyright
13   *    notice, this list of conditions and the following disclaimer. 
14   *
15   * 2. Redistributions in binary form must reproduce the above copyright
16   *    notice, this list of conditions and the following disclaimer in
17   *    the documentation and/or other materials provided with the
18   *    distribution.
19   *
20   * 3. The end-user documentation included with the redistribution, if
21   *    any, must include the following acknowlegement:  
22   *       "This product includes software developed by the 
23   *        ObjectStyle Group (http://objectstyle.org/)."
24   *    Alternately, this acknowlegement may appear in the software itself,
25   *    if and wherever such third-party acknowlegements normally appear.
26   *
27   * 4. The names "ObjectStyle Group" and "Cayenne" 
28   *    must not be used to endorse or promote products derived
29   *    from this software without prior written permission. For written 
30   *    permission, please contact andrus@objectstyle.org.
31   *
32   * 5. Products derived from this software may not be called "ObjectStyle"
33   *    nor may "ObjectStyle" appear in their names without prior written
34   *    permission of the ObjectStyle Group.
35   *
36   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
37   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
38   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
39   * DISCLAIMED.  IN NO EVENT SHALL THE OBJECTSTYLE GROUP OR
40   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
41   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
42   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
43   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
44   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
45   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
46   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
47   * SUCH DAMAGE.
48   * ====================================================================
49   *
50   * This software consists of voluntary contributions made by many
51   * individuals on behalf of the ObjectStyle Group.  For more
52   * information on the ObjectStyle Group, please see
53   * <http://objectstyle.org/>.
54   *
55   */
56  package org.objectstyle.cayenne.wocompat;
57  
58  import java.io.BufferedWriter;
59  import java.io.File;
60  import java.io.FileNotFoundException;
61  import java.io.FileWriter;
62  import java.io.IOException;
63  import java.io.InputStream;
64  import java.io.Writer;
65  import java.util.Iterator;
66  import java.util.List;
67  import java.util.Map;
68  
69  import org.objectstyle.cayenne.CayenneRuntimeException;
70  import org.objectstyle.cayenne.wocompat.parser.Parser;
71  
72  /**
73   * A <b>PropertyListSerialization</b> is a utility class 
74   * that reads and stores files in NeXT/Apple
75   * property list format. Unlike corresponding WebObjects 
76   * class, <code>PropertyListSerialization</code> uses standard
77   * Java collections (lists and maps) to store property lists.
78   * 
79   * @author Andrei Adamchik
80   */
81  public class PropertyListSerialization {
82    /**
83     * Reads a property list file. Returns a property list object, that is
84     * normally a java.util.List or a java.util.Map, but can also be a String
85     * or a Number. 
86     */
87    public static Object propertyListFromFile(File f) throws FileNotFoundException {
88      if (!f.isFile()) {
89        throw new FileNotFoundException("No such file: " + f);
90      }
91  
92      return new Parser(f).propertyList();
93    }
94  
95    /**
96     * Reads a property list data from InputStream. Returns a property list o
97     * bject, that is normally a java.util.List or a java.util.Map, 
98     * but can also be a String or a Number. 
99     */
100   public static Object propertyListFromStream(InputStream in) {
101     return new Parser(in).propertyList();
102   }
103 
104   /**
105    * Saves property list to file.
106    */
107   public static void propertyListToFile(File f, Object plist) {
108     try {
109       BufferedWriter out = new BufferedWriter(new FileWriter(f));
110       try {
111         writeObject("", out, plist);
112       } finally {
113         out.close();
114       }
115     } catch (IOException ioex) {
116       throw new CayenneRuntimeException("Error saving plist.", ioex);
117     }
118   }
119 
120     /**
121      * Internal method to recursively write a property list object.
122      */
123   protected static void writeObject(String offset, Writer out, Object plist)
124     throws IOException {
125     if (plist == null) {
126       return;
127     }
128 
129     if (plist instanceof List) {
130       List list = (List) plist;
131 
132       out.write('\n');
133       out.write(offset);
134 
135       if (list.size() == 0) {
136         out.write("()");
137         return;
138       }
139 
140       out.write("(\n");
141 
142       String childOffset = offset + "   ";
143       Iterator it = list.iterator();
144       boolean appended = false;
145       while (it.hasNext()) {
146         // Java collections can contain nulls, skip them
147         Object obj = it.next();
148         if (obj != null) {
149           if (appended) {
150             out.write(", \n");
151           }
152 
153           out.write(childOffset);
154           writeObject(childOffset, out, obj);
155           appended = true;
156         }
157       }
158 
159       out.write('\n');
160       out.write(offset);
161       out.write(')');
162     } else if (plist instanceof Map) {
163       Map map = (Map) plist;
164       out.write('\n');
165       out.write(offset);
166 
167       if (map.size() == 0) {
168         out.write("{}");
169         return;
170       }
171 
172       out.write("{");
173 
174       String childOffset = offset + "    ";
175 
176       Iterator it = map.keySet().iterator();
177       while (it.hasNext()) {
178         // Java collections can contain nulls, skip them
179         Object key = it.next();
180         if (key == null) {
181           continue;
182         }
183         Object obj = map.get(key);
184         if (obj == null) {
185           continue;
186         }
187         out.write('\n');
188         out.write(childOffset);
189         out.write(quoteString(key.toString()));
190         out.write(" = ");
191         writeObject(childOffset, out, obj);
192         out.write(';');
193       }
194 
195       out.write('\n');
196       out.write(offset);
197       out.write('}');
198     } else if (plist instanceof String) {
199       out.write(quoteString(plist.toString()));
200     } else if (plist instanceof Number) {
201       out.write(plist.toString());
202     } else {
203       throw new CayenneRuntimeException(
204         "Unsupported class for property list serialization: "
205           + plist.getClass().getName());
206     }
207   }
208 
209   /** 
210    * Escapes all doublequotes and backslashes.
211    */
212   protected static String escapeString(String str) {
213     char[] chars = str.toCharArray();
214     int len = chars.length;
215     StringBuffer buf = new StringBuffer(len + 3);
216 
217     for (int i = 0; i < len; i++) {
218       if (chars[i] == '\"' || chars[i] == '\\') {
219         buf.append('\\');
220       }      
221       buf.append(chars[i]);
222     }
223 
224     return buf.toString();
225   }
226 
227     /**
228      * Returns a quoted Stirng, with all the escapes preprocessed.
229      * May return an unquoted String if it contains on special
230      * characters, such as spaces, doublequotes and braces.
231      */
232   protected static String quoteString(String str) {
233     boolean shouldQuote = false;
234     
235     // scan string for special chars, 
236         // if we have them, string must be quoted
237     String special = " \\\"{}();,-\'";
238     char[] chars = str.toCharArray();
239     int len = chars.length;
240     for (int i = 0; i < len; i++) {
241       if (special.indexOf(chars[i]) >= 0) {
242         shouldQuote = true;
243         break;
244       }
245     }
246 
247     str = escapeString(str);
248     return (shouldQuote) ? '\"' + str + '\"' : str;
249   }
250 }