View Javadoc

1   ////////////////////////////////////////////////////////////////////////////////
2   // MillScript: an Open Spice interpreter and batch website creation tool
3   // Copyright (C) 2001-2004 Open World Ltd
4   // Copyright (C) 2005 Kevin Rogers
5   //
6   // This file is part of MillScript.
7   //
8   // MillScript is free software; you can redistribute it and/or modify it under
9   // the terms of the GNU General Public License as published by the Free
10  // Software Foundation; either version 2 of the License, or (at your option)
11  // any later version.
12  //
13  // MillScript is distributed in the hope that it will be useful, but WITHOUT
14  // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
15  // FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
16  // more details.
17  //
18  // You should have received a copy of the GNU General Public License along with
19  // MillScript; if not, write to the Free Software Foundation, Inc., 59 Temple
20  // Place, Suite 330, Boston, MA  02111-1307  USA
21  ////////////////////////////////////////////////////////////////////////////////
22  package org.millscript.millscript.datatypes;
23  
24  import org.millscript.commons.util.IList;
25  import org.millscript.commons.util.IMap;
26  import org.millscript.commons.util.ListIterator;
27  import org.millscript.commons.util.Maplet;
28  import org.millscript.commons.util.list.IEmptyList;
29  import org.millscript.commons.util.list.IJavaUtilList;
30  import org.millscript.commons.util.list.IMapletList;
31  import org.millscript.commons.util.list.IStringList;
32  import org.millscript.commons.util.maplet.IMapEntryMaplet;
33  import org.millscript.commons.vfs.VEntry;
34  import org.millscript.commons.vfs.VFolder;
35  import org.millscript.millscript.alert.Alerts;
36  
37  import java.util.ArrayList;
38  import java.util.List;
39  import java.util.Map;
40  
41  /**
42   * This is a utility class for constructing lists from objects.
43   */
44  public abstract class ListFactory {
45  
46      /**
47       * Returns a list made from the specified object.
48       *
49       * @param obj   the object to make a list from
50       * @return  a List made from the specified object
51       */
52      @SuppressWarnings( "unchecked" )
53      public static final IList make( final Object obj ) {
54          if ( obj instanceof IList ) {
55              // This handles MillScript-Util Lists
56              return (IList) obj;
57          } else if ( obj instanceof List ) {
58              // This handles java.util.Lists
59              return new IJavaUtilList< Object >( (List) obj );
60          } else if ( obj instanceof String ) {
61              // This handles Strings as Maps(char pos to Character)
62              return new IStringList( (String) obj );
63          } else if ( obj instanceof Maplet ) {
64              // This handles Maplets as a List(of the key and value)
65              return new IMapletList< Object >( (Maplet) obj );
66          } else if ( obj instanceof Map.Entry ) {
67              // This handles Map.Entry as a List(of the key and value)
68              return new IMapletList< Object >(
69                  new IMapEntryMaplet< Object, Object >( (Map.Entry) obj )
70              );
71          } else if ( obj instanceof IMap ) {
72              return ((IMap) obj).valueList( true );
73          } else if ( obj instanceof ListAware ) {
74              return ((ListAware)obj).asList();
75          } else if ( obj instanceof VFolder ) {
76              // TODO - This could be more efficient if we make a VFolder a
77              // List...
78              final java.util.List< VEntry > entries = ((VFolder) obj).listEntries();
79              if ( entries == null ) {
80                  return IEmptyList.EMPTY_LIST;
81              } else {
82                  return new IJavaUtilList< VEntry >( entries );
83              }
84          } else {
85              throw(
86                  Alerts.eval(
87                      "Cannot create list view for this object",
88                      "Not all classes can be viewed as lists"
89                  ).culprit( "object", obj ).mishap()
90              );
91          }
92      }
93  
94      /**
95       * Checks if the two specified arguments are of the same type, but only for
96       * list compatible types.
97       *
98       * @param x first object to compare
99       * @param y second object to compare
100      * @return  <code>true</code> if both objects are of the same type and list
101      * compatible, <code>false</code> otherwise
102      */
103     public static final boolean sameAs( final Object x, final Object y ) {
104         return (
105             x instanceof IList && y instanceof IList ||
106             x instanceof List && y instanceof List ||
107             x instanceof String && y instanceof String ||
108             x instanceof Maplet && y instanceof Maplet ||
109             x instanceof Map.Entry && y instanceof Map.Entry ||
110             x instanceof ListAware && ((ListAware)x).sameAs( y )
111         );
112     }
113 
114     /**
115      * Returns an object of the specified type, made from the specified list.
116      * This operation is essentially the reverse of the <code>make</code>
117      * method, above. e.g. if the target type is a String, the list is taken to
118      * be a list of characters making up a new string.
119      *
120      * @param obj   the target object type
121      * @param x     the list of constituent parts
122      * @return  an object of the target type, made from the specified list
123      */
124     public static final Object unmake( final Object obj, final IList< ? > x ) {
125         if ( obj instanceof String ) {
126             StringBuffer buff = new StringBuffer( x.size() );
127             ListIterator< ? > it = x.iterator( true );
128             while ( it.hasNext() ) {
129                 buff.append( ( (Character)it.nextValue() ).charValue() );
130             }
131             return buff.toString();
132         } else if ( obj instanceof IList ) {
133             return x;
134         } else if ( obj instanceof List ) {
135             final ArrayList< Object > list = new ArrayList< Object >( x.size() );
136             ListIterator< ? > it = x.iterator( true );
137             while ( it.hasNext() ) {
138                 list.add( it.nextValue() );
139             }
140             return list;
141         } else if ( obj instanceof ListAware ) {
142             return ((ListAware)obj).asOriginal( x );
143         } else {
144             throw(
145                 Alerts.eval(
146                 "Cannot undo list conversion",
147                 "Not all classes have reversible list conversions"
148                 ).culprit( "object", obj ).mishap()
149             );
150         }
151     }
152 
153     /**
154      * Hidden constructor.
155      */
156     private ListFactory() {
157     }
158 
159 }