Source Code Cross Referenced for ArrayValue.java in  » EJB-Server-resin-3.1.5 » quercus » com » caucho » quercus » env » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » EJB Server resin 3.1.5 » quercus » com.caucho.quercus.env 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


0001:        /*
0002:         * Copyright (c) 1998-2008 Caucho Technology -- all rights reserved
0003:         *
0004:         * This file is part of Resin(R) Open Source
0005:         *
0006:         * Each copy or derived work must preserve the copyright notice and this
0007:         * notice unmodified.
0008:         *
0009:         * Resin Open Source is free software; you can redistribute it and/or modify
0010:         * it under the terms of the GNU General Public License as published by
0011:         * the Free Software Foundation; either version 2 of the License, or
0012:         * (at your option) any later version.
0013:         *
0014:         * Resin Open Source is distributed in the hope that it will be useful,
0015:         * but WITHOUT ANY WARRANTY; without even the implied warranty of
0016:         * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, or any warranty
0017:         * of NON-INFRINGEMENT.  See the GNU General Public License for more
0018:         * details.
0019:         *
0020:         * You should have received a copy of the GNU General Public License
0021:         * along with Resin Open Source; if not, write to the
0022:         *
0023:         *   Free Software Foundation, Inc.
0024:         *   59 Temple Place, Suite 330
0025:         *   Boston, MA 02111-1307  USA
0026:         *
0027:         * @author Scott Ferguson
0028:         */
0029:
0030:        package com.caucho.quercus.env;
0031:
0032:        import com.caucho.quercus.Location;
0033:        import com.caucho.quercus.function.Marshal;
0034:        import com.caucho.quercus.function.MarshalFactory;
0035:        import com.caucho.vfs.WriteStream;
0036:
0037:        import java.io.IOException;
0038:        import java.io.Serializable;
0039:        import java.lang.reflect.Array;
0040:        import java.util.*;
0041:        import java.util.logging.Level;
0042:        import java.util.logging.Logger;
0043:
0044:        /**
0045:         * Represents a PHP array value.
0046:         */
0047:        abstract public class ArrayValue extends Value {
0048:            private static final Logger log = Logger.getLogger(ArrayValue.class
0049:                    .getName());
0050:
0051:            protected static final StringValue KEY = new StringBuilderValue(
0052:                    "key");
0053:            protected static final StringValue VALUE = new StringBuilderValue(
0054:                    "value");
0055:
0056:            public static final GetKey GET_KEY = new GetKey();
0057:            public static final GetValue GET_VALUE = new GetValue();
0058:
0059:            protected Entry _current;
0060:
0061:            protected ArrayValue() {
0062:            }
0063:
0064:            /**
0065:             * Returns the type.
0066:             */
0067:            @Override
0068:            public String getType() {
0069:                return "array";
0070:            }
0071:
0072:            /**
0073:             * Returns the ValueType.
0074:             */
0075:            @Override
0076:            public ValueType getValueType() {
0077:                return ValueType.ARRAY;
0078:            }
0079:
0080:            /**
0081:             * Converts to a boolean.
0082:             */
0083:            @Override
0084:            public boolean toBoolean() {
0085:                return getSize() != 0;
0086:            }
0087:
0088:            /**
0089:             * Converts to a string.
0090:             */
0091:            @Override
0092:            public String toString() {
0093:                return "Array";
0094:            }
0095:
0096:            /**
0097:             * Converts to an object.
0098:             */
0099:            public Object toObject() {
0100:                return null;
0101:            }
0102:
0103:            /**
0104:             * Converts to a java object.
0105:             */
0106:            @Override
0107:            public Object toJavaObject() {
0108:                return this ;
0109:            }
0110:
0111:            //
0112:            // Conversions
0113:            //
0114:
0115:            /**
0116:             * Converts to an object.
0117:             */
0118:            @Override
0119:            public Value toArray() {
0120:                return this ;
0121:            }
0122:
0123:            /**
0124:             * Converts to an array value
0125:             */
0126:            @Override
0127:            public ArrayValue toArrayValue(Env env) {
0128:                return this ;
0129:            }
0130:
0131:            /**
0132:             * Converts to an object.
0133:             */
0134:            @Override
0135:            public Value toObject(Env env) {
0136:                Value obj = env.createObject();
0137:
0138:                for (Entry entry = getHead(); entry != null; entry = entry._next) {
0139:                    Value key = entry.getKey();
0140:
0141:                    if (key instanceof  StringValue) {
0142:                        // XXX: intern?
0143:                        obj.putField(env, key.toString(), entry.getValue());
0144:                    }
0145:                }
0146:
0147:                return obj;
0148:            }
0149:
0150:            /**
0151:             * Converts to a java List object.
0152:             */
0153:            @Override
0154:            public Collection toJavaCollection(Env env, Class type) {
0155:                Collection coll = null;
0156:
0157:                if (type.isAssignableFrom(HashSet.class)) {
0158:                    coll = new HashSet();
0159:                } else if (type.isAssignableFrom(TreeSet.class)) {
0160:                    coll = new TreeSet();
0161:                } else {
0162:                    try {
0163:                        coll = (Collection) type.newInstance();
0164:                    } catch (Throwable e) {
0165:                        log.log(Level.FINE, e.toString(), e);
0166:                        env.warning(L.l("Can't assign array to {0}", type
0167:                                .getName()));
0168:
0169:                        return null;
0170:                    }
0171:                }
0172:
0173:                for (Entry entry = getHead(); entry != null; entry = entry._next) {
0174:                    coll.add(entry.getValue().toJavaObject());
0175:                }
0176:
0177:                return coll;
0178:            }
0179:
0180:            /**
0181:             * Converts to a java List object.
0182:             */
0183:            @Override
0184:            public List toJavaList(Env env, Class type) {
0185:                List list = null;
0186:
0187:                if (type.isAssignableFrom(ArrayList.class)) {
0188:                    list = new ArrayList();
0189:                } else if (type.isAssignableFrom(LinkedList.class)) {
0190:                    list = new LinkedList();
0191:                } else if (type.isAssignableFrom(Vector.class)) {
0192:                    list = new Vector();
0193:                } else {
0194:                    try {
0195:                        list = (List) type.newInstance();
0196:                    } catch (Throwable e) {
0197:                        log.log(Level.FINE, e.toString(), e);
0198:                        env.warning(L.l("Can't assign array to {0}", type
0199:                                .getName()));
0200:
0201:                        return null;
0202:                    }
0203:                }
0204:
0205:                for (Entry entry = getHead(); entry != null; entry = entry._next) {
0206:                    list.add(entry.getValue().toJavaObject());
0207:                }
0208:
0209:                return list;
0210:            }
0211:
0212:            /**
0213:             * Converts to a java object.
0214:             */
0215:            @Override
0216:            public Map toJavaMap(Env env, Class type) {
0217:                Map map = null;
0218:
0219:                if (type.isAssignableFrom(TreeMap.class)) {
0220:                    map = new TreeMap();
0221:                } else if (type.isAssignableFrom(LinkedHashMap.class)) {
0222:                    map = new LinkedHashMap();
0223:                } else {
0224:                    try {
0225:                        map = (Map) type.newInstance();
0226:                    } catch (Throwable e) {
0227:                        log.log(Level.FINE, e.toString(), e);
0228:
0229:                        env.warning(L.l("Can't assign array to {0}", type
0230:                                .getName()));
0231:
0232:                        return null;
0233:                    }
0234:                }
0235:
0236:                for (Entry entry = getHead(); entry != null; entry = entry._next) {
0237:                    map.put(entry.getKey().toJavaObject(), entry.getValue()
0238:                            .toJavaObject());
0239:                }
0240:
0241:                return map;
0242:            }
0243:
0244:            /**
0245:             * Returns true for an array.
0246:             */
0247:            @Override
0248:            public boolean isArray() {
0249:                return true;
0250:            }
0251:
0252:            /**
0253:             * Copy as a return value
0254:             */
0255:            @Override
0256:            public Value copyReturn() {
0257:                return copy(); // php/3a5e
0258:            }
0259:
0260:            /**
0261:             * Copy for assignment.
0262:             */
0263:            @Override
0264:            abstract public Value copy();
0265:
0266:            /**
0267:             * Copy for serialization
0268:             */
0269:            @Override
0270:            abstract public Value copy(Env env,
0271:                    IdentityHashMap<Value, Value> map);
0272:
0273:            /**
0274:             * Returns the size.
0275:             */
0276:            @Override
0277:            abstract public int getSize();
0278:
0279:            /**
0280:             * Returns the count().
0281:             */
0282:            @Override
0283:            public int getCount(Env env) {
0284:                return getSize();
0285:            }
0286:
0287:            /**
0288:             * Returns the count().
0289:             */
0290:            @Override
0291:            public int getCountRecursive(Env env) {
0292:                env.stub("recursive count of array unimplemented");
0293:
0294:                return getSize();
0295:            }
0296:
0297:            /**
0298:             * Returns true if the value is empty
0299:             */
0300:            @Override
0301:            public boolean isEmpty() {
0302:                return getSize() == 0;
0303:            }
0304:
0305:            /**
0306:             * Clears the array
0307:             */
0308:            abstract public void clear();
0309:
0310:            @Override
0311:            public int cmp(Value rValue) {
0312:                return cmpImpl(rValue, 1);
0313:            }
0314:
0315:            private int cmpImpl(Value rValue, int resultIfKeyMissing) {
0316:                // "if key from operand 1 is not found in operand 2 then
0317:                // arrays are uncomparable, otherwise - compare value by value"
0318:
0319:                // php/335h
0320:
0321:                if (!rValue.isArray())
0322:                    return 1;
0323:
0324:                int lSize = getSize();
0325:                int rSize = rValue.toArray().getSize();
0326:
0327:                if (lSize != rSize)
0328:                    return lSize < rSize ? -1 : 1;
0329:
0330:                for (Map.Entry<Value, Value> entry : entrySet()) {
0331:                    Value lElementValue = entry.getValue();
0332:                    Value rElementValue = rValue.get(entry.getKey());
0333:
0334:                    if (!rElementValue.isset())
0335:                        return resultIfKeyMissing;
0336:
0337:                    int cmp = lElementValue.cmp(rElementValue);
0338:
0339:                    if (cmp != 0)
0340:                        return cmp;
0341:                }
0342:
0343:                return 0;
0344:            }
0345:
0346:            /**
0347:             * Returns true for less than
0348:             */
0349:            @Override
0350:            public boolean lt(Value rValue) {
0351:                // php/335h
0352:                return cmpImpl(rValue, 1) < 0;
0353:            }
0354:
0355:            /**
0356:             * Returns true for less than or equal to
0357:             */
0358:            @Override
0359:            public boolean leq(Value rValue) {
0360:                // php/335h
0361:                return cmpImpl(rValue, 1) <= 0;
0362:            }
0363:
0364:            /**
0365:             * Returns true for greater than
0366:             */
0367:            @Override
0368:            public boolean gt(Value rValue) {
0369:                // php/335h
0370:                return cmpImpl(rValue, -1) > 0;
0371:            }
0372:
0373:            /**
0374:             * Returns true for greater than or equal to
0375:             */
0376:            @Override
0377:            public boolean geq(Value rValue) {
0378:                // php/335h
0379:                return cmpImpl(rValue, -1) >= 0;
0380:            }
0381:
0382:            /**
0383:             * Adds a new value.
0384:             */
0385:            @Override
0386:            abstract public Value put(Value key, Value value);
0387:
0388:            /**
0389:             * Add
0390:             */
0391:            @Override
0392:            abstract public Value put(Value value);
0393:
0394:            /**
0395:             * Add to front.
0396:             */
0397:            abstract public ArrayValue unshift(Value value);
0398:
0399:            /**
0400:             * Splices.
0401:             */
0402:            abstract public ArrayValue splice(int begin, int end,
0403:                    ArrayValue replace);
0404:
0405:            /**
0406:             * Returns the value as an array.
0407:             */
0408:            @Override
0409:            public Value getArray(Value index) {
0410:                Value value = get(index);
0411:
0412:                Value array = value.toAutoArray();
0413:
0414:                if (value != array) {
0415:                    value = array;
0416:
0417:                    put(index, value);
0418:                }
0419:
0420:                return value;
0421:            }
0422:
0423:            /**
0424:             * Returns the value as an argument which may be a reference.
0425:             */
0426:            @Override
0427:            abstract public Value getArg(Value index);
0428:
0429:            /**
0430:             * Returns the field value, creating an object if it's unset.
0431:             */
0432:            @Override
0433:            public Value getObject(Env env, Value fieldName) {
0434:                Value value = get(fieldName);
0435:
0436:                Value object = value.toAutoObject(env);
0437:                if (value != object) {
0438:                    value = object;
0439:
0440:                    put(fieldName, value);
0441:                }
0442:
0443:                return value;
0444:            }
0445:
0446:            /**
0447:             * Sets the array ref.
0448:             */
0449:            @Override
0450:            abstract public Value putRef();
0451:
0452:            /**
0453:             * Creatse a tail index.
0454:             */
0455:            abstract public Value createTailKey();
0456:
0457:            /**
0458:             * Returns a union of this array and the rValue as array.
0459:             * If the rValue is not an array, the returned union contains the elements
0460:             * of this array only.
0461:             *
0462:             * To append a value to this ArrayValue use the {@link #put(Value)} method.
0463:             */
0464:            @Override
0465:            public Value add(Value rValue) {
0466:                rValue = rValue.toValue();
0467:
0468:                if (!(rValue instanceof  ArrayValue))
0469:                    return copy();
0470:
0471:                ArrayValue rArray = (ArrayValue) rValue;
0472:
0473:                ArrayValue result = new ArrayValueImpl(rArray);
0474:
0475:                for (Entry entry = getHead(); entry != null; entry = entry._next) {
0476:                    result.put(entry.getKey(), entry.getValue());
0477:                }
0478:
0479:                return result;
0480:            }
0481:
0482:            @Override
0483:            public Iterator<Map.Entry<Value, Value>> getIterator(Env env) {
0484:                return new EntryIterator(getHead());
0485:            }
0486:
0487:            @Override
0488:            public Iterator<Value> getKeyIterator(Env env) {
0489:                return new KeyIterator(getHead());
0490:            }
0491:
0492:            @Override
0493:            public Iterator<Value> getValueIterator(Env env) {
0494:                return new ValueIterator(getHead());
0495:            }
0496:
0497:            /**
0498:             * Gets a new value.
0499:             */
0500:            @Override
0501:            abstract public Value get(Value key);
0502:
0503:            /**
0504:             * Returns the value in the array as-is.
0505:             * (i.e. without calling toValue() on it).
0506:             */
0507:            public Value getRaw(Value key) {
0508:                return get(key);
0509:            }
0510:
0511:            /**
0512:             * Removes a value.
0513:             */
0514:            @Override
0515:            abstract public Value remove(Value key);
0516:
0517:            /**
0518:             * Returns the array ref.
0519:             */
0520:            @Override
0521:            abstract public Var getRef(Value index);
0522:
0523:            /**
0524:             * Returns an iterator of the entries.
0525:             */
0526:            public Set<Value> keySet() {
0527:                return new KeySet();
0528:            }
0529:
0530:            /**
0531:             * Returns a set of all the of the entries.
0532:             */
0533:            public Set<Map.Entry<Value, Value>> entrySet() {
0534:                return new EntrySet();
0535:            }
0536:
0537:            /**
0538:             * Returns a collection of the values.
0539:             */
0540:            public Collection<Value> values() {
0541:                return new ValueCollection();
0542:            }
0543:
0544:            /**
0545:             * Convenience for lib.
0546:             */
0547:            public void put(String key, String value) {
0548:                // XXX: this needs an Env arg because of i18n
0549:                // XXX: but some  modules have arrays that are static constants
0550:                put(StringValue.create(key), StringValue.create(value));
0551:            }
0552:
0553:            /**
0554:             * Convenience for lib.
0555:             */
0556:            public void put(Env env, String key, String value) {
0557:                put(env.createString(key), env.createString(value));
0558:            }
0559:
0560:            /**
0561:             * Convenience for lib.
0562:             */
0563:            public void put(String key, char value) {
0564:                // XXX: this needs an Env arg because of i18n
0565:                put(StringValue.create(key), StringValue.create(value));
0566:            }
0567:
0568:            /**
0569:             * Convenience for lib.
0570:             */
0571:            public void put(String key, long value) {
0572:                // XXX: this needs an Env arg because of i18n
0573:                put(StringValue.create(key), new LongValue(value));
0574:            }
0575:
0576:            /**
0577:             * Convenience for lib.
0578:             */
0579:            public void put(Env env, String key, long value) {
0580:                put(env.createString(key), new LongValue(value));
0581:            }
0582:
0583:            /**
0584:             * Convenience for lib.
0585:             */
0586:            public void put(String key, double value) {
0587:                // XXX: this needs an Env arg because of i18n
0588:                put(StringValue.create(key), new DoubleValue(value));
0589:            }
0590:
0591:            /**
0592:             * Convenience for lib.
0593:             */
0594:            public void put(String key, boolean value) {
0595:                // XXX: this needs an Env arg because of i18n
0596:                put(StringValue.create(key), value ? BooleanValue.TRUE
0597:                        : BooleanValue.FALSE);
0598:            }
0599:
0600:            /**
0601:             * Convenience for lib.
0602:             */
0603:            public void put(Env env, String key, boolean value) {
0604:                put(env.createString(key), value ? BooleanValue.TRUE
0605:                        : BooleanValue.FALSE);
0606:            }
0607:
0608:            /**
0609:             * Convenience for lib.
0610:             */
0611:            public void put(String value) {
0612:                // XXX: this needs an Env arg because of i18n
0613:                put(StringValue.create(value));
0614:            }
0615:
0616:            /**
0617:             * Convenience for lib.
0618:             */
0619:            public void put(long value) {
0620:                put(new LongValue(value));
0621:            }
0622:
0623:            /**
0624:             * Appends as an argument - only called from compiled code
0625:             *
0626:             * XXX: change name to appendArg
0627:             */
0628:            public ArrayValue append(Value key, Value value) {
0629:                put(key, value);
0630:
0631:                return this ;
0632:            }
0633:
0634:            /**
0635:             * Appends as an argument - only called from compiled code
0636:             *
0637:             * XXX: change name to appendArg
0638:             */
0639:            public ArrayValue append(Value value) {
0640:                put(value);
0641:
0642:                return this ;
0643:            }
0644:
0645:            /**
0646:             * Appends as an argument - only called from compiled code
0647:             *
0648:             * XXX: change name to appendArg
0649:             */
0650:            public void putAll(ArrayValue array) {
0651:                for (Map.Entry<Value, Value> entry : array.entrySet())
0652:                    put(entry.getKey(), entry.getValue());
0653:            }
0654:
0655:            /**
0656:             * Convert to an array.
0657:             */
0658:            public static Value toArray(Value value) {
0659:                value = value.toValue();
0660:
0661:                if (value instanceof  ArrayValue)
0662:                    return value;
0663:                else
0664:                    return new ArrayValueImpl().put(value);
0665:            }
0666:
0667:            /**
0668:             * Prints the value.
0669:             * @param env
0670:             */
0671:            @Override
0672:            public void print(Env env) {
0673:                env.print("Array");
0674:            }
0675:
0676:            /**
0677:             * Pops the top value.
0678:             */
0679:            abstract public Value pop();
0680:
0681:            /**
0682:             * Shuffles the array
0683:             */
0684:            abstract public void shuffle();
0685:
0686:            /**
0687:             * Returns the head.
0688:             */
0689:            abstract public Entry getHead();
0690:
0691:            /**
0692:             * Returns the tail.
0693:             */
0694:            abstract protected Entry getTail();
0695:
0696:            /**
0697:             * Returns the current value.
0698:             */
0699:            @Override
0700:            public Value current() {
0701:                if (_current != null)
0702:                    return _current.getValue();
0703:                else
0704:                    return BooleanValue.FALSE;
0705:            }
0706:
0707:            /**
0708:             * Returns the current key
0709:             */
0710:            @Override
0711:            public Value key() {
0712:                if (_current != null)
0713:                    return _current.getKey();
0714:                else
0715:                    return NullValue.NULL;
0716:            }
0717:
0718:            /**
0719:             * Returns true if there are more elements.
0720:             */
0721:            @Override
0722:            public boolean hasCurrent() {
0723:                return _current != null;
0724:            }
0725:
0726:            /**
0727:             * Returns the next value.
0728:             */
0729:            @Override
0730:            public Value next() {
0731:                if (_current != null)
0732:                    _current = _current._next;
0733:
0734:                return current();
0735:            }
0736:
0737:            /**
0738:             * Returns the previous value.
0739:             */
0740:            public Value prev() {
0741:                if (_current != null)
0742:                    _current = _current._prev;
0743:
0744:                return current();
0745:            }
0746:
0747:            /**
0748:             * The each iterator
0749:             */
0750:            public Value each() {
0751:                if (_current == null)
0752:                    return NullValue.NULL;
0753:
0754:                ArrayValue result = new ArrayValueImpl();
0755:
0756:                result.put(LongValue.ZERO, _current.getKey());
0757:                result.put(KEY, _current.getKey());
0758:
0759:                result.put(LongValue.ONE, _current.getValue());
0760:                result.put(VALUE, _current.getValue());
0761:
0762:                _current = _current._next;
0763:
0764:                return result;
0765:            }
0766:
0767:            /**
0768:             * Returns the first value.
0769:             */
0770:            public Value reset() {
0771:                _current = getHead();
0772:
0773:                return current();
0774:            }
0775:
0776:            /**
0777:             * Returns the last value.
0778:             */
0779:            public Value end() {
0780:                _current = getTail();
0781:
0782:                return current();
0783:            }
0784:
0785:            /**
0786:             * Returns the corresponding key if this array contains the given value
0787:             *
0788:             * @param value  the value to search for in the array
0789:             *
0790:             * @return the key if it is found in the array, NULL otherwise
0791:             *
0792:             * @throws NullPointerException
0793:             */
0794:            public Value contains(Value value) {
0795:                for (Entry entry = getHead(); entry != null; entry = entry._next) {
0796:                    if (entry.getValue().eq(value))
0797:                        return entry.getKey();
0798:                }
0799:
0800:                return NullValue.NULL;
0801:            }
0802:
0803:            /**
0804:             * Returns the corresponding key if this array contains the given value
0805:             *
0806:             * @param value  the value to search for in the array
0807:             *
0808:             * @return the key if it is found in the array, NULL otherwise
0809:             *
0810:             * @throws NullPointerException
0811:             */
0812:            public Value containsStrict(Value value) {
0813:                for (Entry entry = getHead(); entry != null; entry = entry._next) {
0814:                    if (entry.getValue().eql(value))
0815:                        return entry.getKey();
0816:                }
0817:
0818:                return NullValue.NULL;
0819:            }
0820:
0821:            /**
0822:             * Returns the corresponding valeu if this array contains the given key
0823:             *
0824:             * @param key  the key to search for in the array
0825:             *
0826:             * @return the value if it is found in the array, NULL otherwise
0827:             *
0828:             * @throws NullPointerException
0829:             */
0830:            abstract public Value containsKey(Value key);
0831:
0832:            /**
0833:             * Returns an object array of this array.  This is a copy of this object's
0834:             * backing structure.  Null elements are not included.
0835:             *
0836:             * @return an object array of this array
0837:             */
0838:            public Map.Entry<Value, Value>[] toEntryArray() {
0839:                ArrayList<Map.Entry<Value, Value>> array = new ArrayList<Map.Entry<Value, Value>>(
0840:                        getSize());
0841:
0842:                for (Entry entry = getHead(); entry != null; entry = entry._next)
0843:                    array.add(entry);
0844:
0845:                Map.Entry<Value, Value>[] result = new Entry[array.size()];
0846:
0847:                return array.toArray(result);
0848:            }
0849:
0850:            /**
0851:             * Sorts this array based using the passed Comparator
0852:             *
0853:             * @param comparator the comparator for sorting the array
0854:             * @param resetKeys  true if the keys should not be preserved
0855:             * @param strict  true if alphabetic keys should not be preserved
0856:             */
0857:            public void sort(Comparator<Map.Entry<Value, Value>> comparator,
0858:                    boolean resetKeys, boolean strict) {
0859:                Entry[] entries;
0860:
0861:                entries = new Entry[getSize()];
0862:
0863:                int i = 0;
0864:                for (Entry entry = getHead(); entry != null; entry = entry._next) {
0865:                    entries[i++] = entry;
0866:                }
0867:
0868:                Arrays.sort(entries, comparator);
0869:
0870:                clear();
0871:
0872:                long base = 0;
0873:
0874:                if (!resetKeys)
0875:                    strict = false;
0876:
0877:                for (int j = 0; j < entries.length; j++) {
0878:                    Value key = entries[j].getKey();
0879:
0880:                    if (resetKeys && (!(key instanceof  StringValue) || strict))
0881:                        put(LongValue.create(base++), entries[j].getValue());
0882:                    else
0883:                        put(entries[j].getKey(), entries[j].getValue());
0884:                }
0885:            }
0886:
0887:            /**
0888:             * Serializes the value.
0889:             */
0890:            @Override
0891:            public void serialize(StringBuilder sb) {
0892:                sb.append("a:");
0893:                sb.append(getSize());
0894:                sb.append(":{");
0895:
0896:                for (Entry entry = getHead(); entry != null; entry = entry._next) {
0897:                    entry.getKey().serialize(sb);
0898:                    entry.getValue().serialize(sb);
0899:                }
0900:
0901:                sb.append("}");
0902:            }
0903:
0904:            /**
0905:             * Exports the value.
0906:             */
0907:            @Override
0908:            public void varExport(StringBuilder sb) {
0909:                sb.append("array(");
0910:
0911:                boolean isFirst = true;
0912:                for (Entry entry = getHead(); entry != null; entry = entry._next) {
0913:                    entry.getKey().varExport(sb);
0914:                    sb.append(" => ");
0915:                    entry.getValue().varExport(sb);
0916:                    sb.append(", ");
0917:                }
0918:
0919:                sb.append(")");
0920:            }
0921:
0922:            /**
0923:             * Resets all numerical keys with the first index as base
0924:             *
0925:             * @param base  the initial index
0926:             * @param strict  if true, string keys are also reset
0927:             */
0928:            public boolean keyReset(long base, boolean strict) {
0929:                Entry[] entries;
0930:
0931:                entries = new Entry[getSize()];
0932:
0933:                int i = 0;
0934:                for (Entry entry = getHead(); entry != null; entry = entry._next) {
0935:                    entries[i++] = entry;
0936:                }
0937:
0938:                clear();
0939:
0940:                for (int j = 0; j < entries.length; j++) {
0941:                    Value key = entries[j].getKey();
0942:
0943:                    if (!(key instanceof  StringValue) || strict)
0944:                        put(LongValue.create(base++), entries[j].getValue());
0945:                    else
0946:                        put(entries[j].getKey(), entries[j].getValue());
0947:                }
0948:
0949:                return true;
0950:            }
0951:
0952:            /**
0953:             * Test for equality
0954:             *
0955:             * @param rValue rhs ArrayValue to compare to
0956:             *
0957:             * @return true if this is equal to rValue, false otherwise
0958:             */
0959:            @Override
0960:            public boolean eq(Value rValue) {
0961:                if (rValue == null)
0962:                    return false;
0963:
0964:                for (Map.Entry<Value, Value> entry : entrySet()) {
0965:                    Value entryValue = entry.getValue();
0966:
0967:                    Value entryKey = entry.getKey();
0968:
0969:                    Value rEntryValue = rValue.get(entryKey);
0970:
0971:                    if ((rEntryValue instanceof  ArrayValue)
0972:                            && !entryValue.eq((ArrayValue) rEntryValue))
0973:                        return false;
0974:
0975:                    if (!entryValue.eq(rEntryValue))
0976:                        return false;
0977:                }
0978:
0979:                return true;
0980:            }
0981:
0982:            /**
0983:             * Test for ===
0984:             *
0985:             * @param rValue rhs ArrayValue to compare to
0986:             *
0987:             * @return true if this is equal to rValue, false otherwise
0988:             */
0989:            @Override
0990:            public boolean eql(Value rValue) {
0991:                if (rValue == null)
0992:                    return false;
0993:                else if (getSize() != rValue.getSize())
0994:                    return false;
0995:
0996:                rValue = rValue.toValue();
0997:
0998:                if (!(rValue instanceof  ArrayValue))
0999:                    return false;
1000:
1001:                ArrayValue rArray = (ArrayValue) rValue;
1002:
1003:                Iterator<Map.Entry<Value, Value>> iterA = entrySet().iterator();
1004:                Iterator<Map.Entry<Value, Value>> iterB = rArray.entrySet()
1005:                        .iterator();
1006:
1007:                while (iterA.hasNext() && iterB.hasNext()) {
1008:                    Map.Entry<Value, Value> entryA = iterA.next();
1009:                    Map.Entry<Value, Value> entryB = iterB.next();
1010:
1011:                    if (!entryA.getKey().eql(entryB.getKey()))
1012:                        return false;
1013:
1014:                    if (!entryA.getValue().eql(entryB.getValue()))
1015:                        return false;
1016:                }
1017:
1018:                if (iterA.hasNext() || iterB.hasNext())
1019:                    return false;
1020:                else
1021:                    return true;
1022:            }
1023:
1024:            @Override
1025:            public void varDumpImpl(Env env, WriteStream out, int depth,
1026:                    IdentityHashMap<Value, String> valueSet) throws IOException {
1027:                out.println("array(" + getSize() + ") {");
1028:
1029:                for (Map.Entry<Value, Value> mapEntry : entrySet()) {
1030:                    varDumpEntry(env, out, depth + 1, valueSet, mapEntry);
1031:
1032:                    out.println();
1033:                }
1034:
1035:                printDepth(out, 2 * depth);
1036:
1037:                out.print("}");
1038:            }
1039:
1040:            protected void varDumpEntry(Env env, WriteStream out, int depth,
1041:                    IdentityHashMap<Value, String> valueSet,
1042:                    Map.Entry<Value, Value> mapEntry) throws IOException {
1043:                ArrayValue.Entry entry = (ArrayValue.Entry) mapEntry;
1044:
1045:                entry.varDumpImpl(env, out, depth, valueSet);
1046:            }
1047:
1048:            @Override
1049:            protected void printRImpl(Env env, WriteStream out, int depth,
1050:                    IdentityHashMap<Value, String> valueSet) throws IOException {
1051:                out.println("Array");
1052:                printDepth(out, 8 * depth);
1053:                out.println("(");
1054:
1055:                for (Map.Entry<Value, Value> mapEntry : entrySet()) {
1056:                    printREntry(env, out, depth, valueSet, mapEntry);
1057:                }
1058:
1059:                printDepth(out, 8 * depth);
1060:                out.println(")");
1061:            }
1062:
1063:            protected void printREntry(Env env, WriteStream out, int depth,
1064:                    IdentityHashMap<Value, String> valueSet,
1065:                    Map.Entry<Value, Value> mapEntry) throws IOException {
1066:                ArrayValue.Entry entry = (ArrayValue.Entry) mapEntry;
1067:
1068:                entry.printRImpl(env, out, depth, valueSet);
1069:            }
1070:
1071:            public final static class Entry implements  Map.Entry<Value, Value>,
1072:                    Serializable {
1073:                final Value _key;
1074:                Value _value;
1075:
1076:                Entry _prev;
1077:                Entry _next;
1078:
1079:                Entry _prevHash;
1080:                Entry _nextHash;
1081:
1082:                int _index;
1083:
1084:                public Entry(Value key) {
1085:                    _key = key;
1086:                    _value = NullValue.NULL;
1087:                }
1088:
1089:                public Entry(Value key, Value value) {
1090:                    _key = key;
1091:                    _value = value;
1092:                }
1093:
1094:                public Entry getNext() {
1095:                    return _next;
1096:                }
1097:
1098:                public Value getRawValue() {
1099:                    return _value;
1100:                }
1101:
1102:                public Value getValue() {
1103:                    return _value.toValue();
1104:                }
1105:
1106:                public Value getKey() {
1107:                    return _key;
1108:                }
1109:
1110:                public Value toValue() {
1111:                    // The value may be a var
1112:                    // XXX: need test
1113:                    return _value.toValue();
1114:                }
1115:
1116:                /**
1117:                 * Argument used/declared as a ref.
1118:                 */
1119:                public Var toRefVar() {
1120:                    // php/376a
1121:
1122:                    Value val = _value;
1123:
1124:                    if (val instanceof  Var)
1125:                        return (Var) val;
1126:                    else {
1127:                        Var var = new Var(val);
1128:
1129:                        _value = var;
1130:
1131:                        return var;
1132:                    }
1133:                }
1134:
1135:                /**
1136:                 * Converts to an argument value.
1137:                 */
1138:                public Value toArgValue() {
1139:                    return _value.toValue();
1140:                }
1141:
1142:                public Value setValue(Value value) {
1143:                    Value oldValue = _value;
1144:
1145:                    _value = value;
1146:
1147:                    return oldValue;
1148:                }
1149:
1150:                /**
1151:                 * Converts to a variable reference (for function  arguments)
1152:                 */
1153:                public Value toRef() {
1154:                    Value value = _value;
1155:
1156:                    if (value instanceof  Var)
1157:                        return new RefVar((Var) value);
1158:                    else {
1159:                        _value = new Var(value);
1160:
1161:                        return new RefVar((Var) _value);
1162:                    }
1163:                }
1164:
1165:                /**
1166:                 * Converts to a variable reference (for function  arguments)
1167:                 */
1168:                public Value toArgRef() {
1169:                    Value value = _value;
1170:
1171:                    if (value instanceof  Var)
1172:                        return new RefVar((Var) value);
1173:                    else {
1174:                        _value = new Var(_value);
1175:
1176:                        return new RefVar((Var) _value);
1177:                    }
1178:                }
1179:
1180:                public Value toArg() {
1181:                    // php/39a4
1182:                    Value value = _value;
1183:
1184:                    // php/39aj
1185:                    if (value instanceof  Var)
1186:                        return value;
1187:                    else {
1188:                        _value = new Var(value);
1189:
1190:                        return _value;
1191:                    }
1192:                }
1193:
1194:                public void varDumpImpl(Env env, WriteStream out, int depth,
1195:                        IdentityHashMap<Value, String> valueSet)
1196:                        throws IOException {
1197:                    printDepth(out, 2 * depth);
1198:                    out.print("[");
1199:
1200:                    if (_key instanceof  StringValue)
1201:                        out.print("\"" + _key + "\"");
1202:                    else
1203:                        out.print(_key);
1204:
1205:                    out.println("]=>");
1206:
1207:                    printDepth(out, 2 * depth);
1208:
1209:                    _value.varDump(env, out, depth, valueSet);
1210:                }
1211:
1212:                protected void printRImpl(Env env, WriteStream out, int depth,
1213:                        IdentityHashMap<Value, String> valueSet)
1214:                        throws IOException {
1215:                    printDepth(out, 8 * depth);
1216:                    out.print("    [");
1217:                    out.print(_key);
1218:                    out.print("] => ");
1219:                    if (_value != null)
1220:                        _value.printR(env, out, depth + 1, valueSet);
1221:                    out.println();
1222:                }
1223:
1224:                private void printDepth(WriteStream out, int depth)
1225:                        throws java.io.IOException {
1226:                    for (int i = depth; i > 0; i--)
1227:                        out.print(' ');
1228:                }
1229:
1230:                @Override
1231:                public String toString() {
1232:                    return "ArrayValue.Entry[" + getKey() + "]";
1233:                }
1234:            }
1235:
1236:            /**
1237:             * Returns the field keys.
1238:             */
1239:            public Value[] getKeyArray(Env env) {
1240:                int len = getSize();
1241:                Value[] keys = new Value[len];
1242:
1243:                Iterator<Value> iter = getKeyIterator(env);
1244:
1245:                for (int i = 0; i < len; i++) {
1246:                    keys[i] = iter.next();
1247:                }
1248:
1249:                return keys;
1250:            }
1251:
1252:            /**
1253:             * Returns the field values.
1254:             */
1255:            public Value[] getValueArray(Env env) {
1256:                int len = getSize();
1257:                Value[] values = new Value[len];
1258:
1259:                Iterator<Value> iter = getValueIterator(env);
1260:
1261:                for (int i = 0; i < len; i++) {
1262:                    values[i] = iter.next();
1263:                }
1264:
1265:                return values;
1266:            }
1267:
1268:            /**
1269:             * Takes the values of this array and puts them in a java array
1270:             */
1271:            public Value[] valuesToArray() {
1272:                Value[] values = new Value[getSize()];
1273:
1274:                int i = 0;
1275:                for (Entry ptr = getHead(); ptr != null; ptr = ptr.getNext()) {
1276:                    values[i++] = ptr.getValue();
1277:                }
1278:
1279:                return values;
1280:            }
1281:
1282:            /**
1283:             * Takes the values of this array, unmarshals them to objects of type
1284:             * <i>elementType</i>, and puts them in a java array.
1285:             */
1286:            @Override
1287:            public Object valuesToArray(Env env, Class elementType) {
1288:                int size = getSize();
1289:
1290:                Object array = Array.newInstance(elementType, size);
1291:
1292:                MarshalFactory factory = env.getModuleContext()
1293:                        .getMarshalFactory();
1294:                Marshal elementMarshal = factory.create(elementType);
1295:
1296:                int i = 0;
1297:
1298:                for (Entry ptr = getHead(); ptr != null; ptr = ptr.getNext()) {
1299:                    Array.set(array, i++, elementMarshal.marshal(env, ptr
1300:                            .getValue(), elementType));
1301:                }
1302:
1303:                return array;
1304:            }
1305:
1306:            public class EntrySet extends AbstractSet<Map.Entry<Value, Value>> {
1307:                EntrySet() {
1308:                }
1309:
1310:                @Override
1311:                public int size() {
1312:                    return ArrayValue.this .getSize();
1313:                }
1314:
1315:                @Override
1316:                public Iterator<Map.Entry<Value, Value>> iterator() {
1317:                    return new EntryIterator(getHead());
1318:                }
1319:            }
1320:
1321:            public class KeySet extends AbstractSet<Value> {
1322:                KeySet() {
1323:                }
1324:
1325:                @Override
1326:                public int size() {
1327:                    return ArrayValue.this .getSize();
1328:                }
1329:
1330:                @Override
1331:                public Iterator<Value> iterator() {
1332:                    return new KeyIterator(getHead());
1333:                }
1334:            }
1335:
1336:            public class ValueCollection extends AbstractCollection<Value> {
1337:                ValueCollection() {
1338:                }
1339:
1340:                @Override
1341:                public int size() {
1342:                    return ArrayValue.this .getSize();
1343:                }
1344:
1345:                @Override
1346:                public Iterator<Value> iterator() {
1347:                    return new ValueIterator(getHead());
1348:                }
1349:            }
1350:
1351:            public static class EntryIterator implements 
1352:                    Iterator<Map.Entry<Value, Value>> {
1353:                private Entry _current;
1354:
1355:                EntryIterator(Entry head) {
1356:                    _current = head;
1357:                }
1358:
1359:                public boolean hasNext() {
1360:                    return _current != null;
1361:                }
1362:
1363:                public Map.Entry<Value, Value> next() {
1364:                    if (_current != null) {
1365:                        Map.Entry<Value, Value> next = _current;
1366:                        _current = _current._next;
1367:
1368:                        return next;
1369:                    } else
1370:                        return null;
1371:                }
1372:
1373:                public void remove() {
1374:                    throw new UnsupportedOperationException();
1375:                }
1376:            }
1377:
1378:            public static class KeyIterator implements  Iterator<Value> {
1379:                private Entry _current;
1380:
1381:                KeyIterator(Entry head) {
1382:                    _current = head;
1383:                }
1384:
1385:                public boolean hasNext() {
1386:                    return _current != null;
1387:                }
1388:
1389:                public Value next() {
1390:                    if (_current != null) {
1391:                        Value next = _current.getKey();
1392:                        _current = _current._next;
1393:
1394:                        return next;
1395:                    } else
1396:                        return null;
1397:                }
1398:
1399:                public void remove() {
1400:                    throw new UnsupportedOperationException();
1401:                }
1402:            }
1403:
1404:            public static class ValueIterator implements  Iterator<Value> {
1405:                private Entry _current;
1406:
1407:                ValueIterator(Entry head) {
1408:                    _current = head;
1409:                }
1410:
1411:                public boolean hasNext() {
1412:                    return _current != null;
1413:                }
1414:
1415:                public Value next() {
1416:                    if (_current != null) {
1417:                        Value next = _current.getValue();
1418:                        _current = _current._next;
1419:
1420:                        return next;
1421:                    } else
1422:                        return null;
1423:                }
1424:
1425:                public void remove() {
1426:                    throw new UnsupportedOperationException();
1427:                }
1428:            }
1429:
1430:            public static class ValueComparator implements 
1431:                    Comparator<Map.Entry<Value, Value>> {
1432:                public static final ValueComparator CMP = new ValueComparator();
1433:
1434:                private ValueComparator() {
1435:                }
1436:
1437:                public int compare(Map.Entry<Value, Value> aEntry,
1438:                        Map.Entry<Value, Value> bEntry) {
1439:                    try {
1440:                        Value aValue = aEntry.getValue();
1441:                        Value bValue = bEntry.getValue();
1442:
1443:                        if (aValue.eq(bValue))
1444:                            return 0;
1445:                        else if (aValue.lt(bValue))
1446:                            return -1;
1447:                        else
1448:                            return 1;
1449:                    } catch (Throwable e) {
1450:                        throw new RuntimeException(e);
1451:                    }
1452:                }
1453:            }
1454:
1455:            public static class KeyComparator implements 
1456:                    Comparator<Map.Entry<Value, Value>> {
1457:                public static final KeyComparator CMP = new KeyComparator();
1458:
1459:                private KeyComparator() {
1460:                }
1461:
1462:                public int compare(Map.Entry<Value, Value> aEntry,
1463:                        Map.Entry<Value, Value> bEntry) {
1464:                    try {
1465:                        Value aKey = aEntry.getKey();
1466:                        Value bKey = bEntry.getKey();
1467:
1468:                        if (aKey.eq(bKey))
1469:                            return 0;
1470:                        else if (aKey.lt(bKey))
1471:                            return -1;
1472:                        else
1473:                            return 1;
1474:                    } catch (Throwable e) {
1475:                        throw new RuntimeException(e);
1476:                    }
1477:                }
1478:            }
1479:
1480:            public static abstract class AbstractGet {
1481:                public abstract Value get(Map.Entry<Value, Value> entry);
1482:            }
1483:
1484:            public static class GetKey extends AbstractGet {
1485:                public static final GetKey GET = new GetKey();
1486:
1487:                private GetKey() {
1488:                }
1489:
1490:                @Override
1491:                public Value get(Map.Entry<Value, Value> entry) {
1492:                    return entry.getKey();
1493:                }
1494:            }
1495:
1496:            public static class GetValue extends AbstractGet {
1497:                public static final GetValue GET = new GetValue();
1498:
1499:                private GetValue() {
1500:                }
1501:
1502:                @Override
1503:                public Value get(Map.Entry<Value, Value> entry) {
1504:                    return entry.getValue();
1505:                }
1506:            }
1507:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.