Source Code Cross Referenced for ObjectExtValue.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.expr.Expr;
0034:        import com.caucho.quercus.expr.StringLiteralExpr;
0035:        import com.caucho.quercus.program.AbstractFunction;
0036:        import com.caucho.vfs.WriteStream;
0037:
0038:        import java.io.IOException;
0039:        import java.io.ObjectInputStream;
0040:        import java.io.ObjectOutputStream;
0041:        import java.io.Serializable;
0042:        import java.util.AbstractSet;
0043:        import java.util.IdentityHashMap;
0044:        import java.util.Iterator;
0045:        import java.util.Map;
0046:        import java.util.Set;
0047:        import java.util.TreeSet;
0048:
0049:        /**
0050:         * Represents a PHP object value.
0051:         */
0052:        public class ObjectExtValue extends ObjectValue implements  Serializable {
0053:            private static final StringValue TO_STRING = new StringBuilderValue(
0054:                    "__toString");
0055:
0056:            private static final int DEFAULT_SIZE = 16;
0057:
0058:            private MethodMap<AbstractFunction> _methodMap;
0059:
0060:            private Entry[] _entries;
0061:            private int _hashMask;
0062:
0063:            private int _size;
0064:            private boolean _isFieldInit;
0065:
0066:            public ObjectExtValue(QuercusClass cl) {
0067:                super (cl);
0068:
0069:                _methodMap = cl.getMethodMap();
0070:
0071:                _entries = new Entry[DEFAULT_SIZE];
0072:                _hashMask = _entries.length - 1;
0073:            }
0074:
0075:            private void init() {
0076:                _entries = new Entry[DEFAULT_SIZE];
0077:                _hashMask = _entries.length - 1;
0078:            }
0079:
0080:            @Override
0081:            protected void setQuercusClass(QuercusClass cl) {
0082:                super .setQuercusClass(cl);
0083:
0084:                _methodMap = cl.getMethodMap();
0085:            }
0086:
0087:            /**
0088:             * Returns the number of entries.
0089:             */
0090:            @Override
0091:            public int getSize() {
0092:                return _size;
0093:            }
0094:
0095:            /**
0096:             * Gets a field value.
0097:             */
0098:            @Override
0099:            public final Value getField(Env env, StringValue name) {
0100:                int hash = name.hashCode() & _hashMask;
0101:
0102:                for (Entry entry = _entries[hash]; entry != null; entry = entry._next) {
0103:                    if (name.equals(entry._key))
0104:                        return entry._value.toValue();
0105:                }
0106:
0107:                Value value = getFieldExt(env, name);
0108:
0109:                if (value != null)
0110:                    return value;
0111:                else
0112:                    return _quercusClass.getField(env, this , name);
0113:            }
0114:
0115:            /**
0116:             * Gets a field value.
0117:             */
0118:            @Override
0119:            public Value getThisField(Env env, StringValue name) {
0120:                int hash = name.hashCode() & _hashMask;
0121:
0122:                for (Entry entry = _entries[hash]; entry != null; entry = entry._next) {
0123:                    if (name.equals(entry._key))
0124:                        return entry._value.toValue();
0125:                }
0126:
0127:                Value value = getFieldExt(env, name);
0128:
0129:                if (value != null)
0130:                    return value;
0131:                else
0132:                    return UnsetValue.UNSET;
0133:            }
0134:
0135:            /**
0136:             * Returns fields not specified by the value.
0137:             */
0138:            protected Value getFieldExt(Env env, StringValue name) {
0139:                return null;
0140:            }
0141:
0142:            /**
0143:             * Returns the array ref.
0144:             */
0145:            @Override
0146:            public Var getFieldRef(Env env, StringValue name) {
0147:                Entry entry = createEntry(name);
0148:
0149:                Value value = entry._value;
0150:
0151:                if (value instanceof  Var)
0152:                    return (Var) value;
0153:
0154:                Var var = new Var(value);
0155:
0156:                entry.setValue(var);
0157:
0158:                return var;
0159:            }
0160:
0161:            /**
0162:             * Returns the array ref.
0163:             */
0164:            @Override
0165:            public Var getThisFieldRef(Env env, StringValue name) {
0166:                Entry entry = createEntry(name);
0167:
0168:                Value value = entry._value;
0169:
0170:                if (value instanceof  Var)
0171:                    return (Var) value;
0172:
0173:                Var var = new Var(value);
0174:
0175:                entry.setValue(var);
0176:
0177:                return var;
0178:            }
0179:
0180:            /**
0181:             * Returns the value as an argument which may be a reference.
0182:             */
0183:            @Override
0184:            public Value getFieldArg(Env env, StringValue name) {
0185:                Entry entry = getEntry(name);
0186:
0187:                if (entry != null)
0188:                    return entry.toArg();
0189:                else
0190:                    return new ArgGetFieldValue(env, this , name);
0191:            }
0192:
0193:            /**
0194:             * Returns the value as an argument which may be a reference.
0195:             */
0196:            @Override
0197:            public Value getThisFieldArg(Env env, StringValue name) {
0198:                Entry entry = getEntry(name);
0199:
0200:                if (entry != null)
0201:                    return entry.toArg();
0202:                else
0203:                    return new ArgGetFieldValue(env, this , name);
0204:            }
0205:
0206:            /**
0207:             * Returns the value as an argument which may be a reference.
0208:             */
0209:            @Override
0210:            public Value getFieldArgRef(Env env, StringValue name) {
0211:                Entry entry = getEntry(name);
0212:
0213:                if (entry != null)
0214:                    return entry.toArg();
0215:                else
0216:                    return new ArgGetFieldValue(env, this , name);
0217:            }
0218:
0219:            /**
0220:             * Returns the value as an argument which may be a reference.
0221:             */
0222:            @Override
0223:            public Value getThisFieldArgRef(Env env, StringValue name) {
0224:                Entry entry = getEntry(name);
0225:
0226:                if (entry != null)
0227:                    return entry.toArg();
0228:                else
0229:                    return new ArgGetFieldValue(env, this , name);
0230:            }
0231:
0232:            /**
0233:             * Adds a new value.
0234:             */
0235:            @Override
0236:            public Value putField(Env env, StringValue name, Value value) {
0237:                Entry entry = getEntry(name);
0238:
0239:                if (entry == null) {
0240:                    Value oldValue = putFieldExt(env, name, value);
0241:
0242:                    if (oldValue != null)
0243:                        return oldValue;
0244:
0245:                    if (!_isFieldInit) {
0246:                        AbstractFunction fieldSet = _quercusClass.getFieldSet();
0247:
0248:                        if (fieldSet != null) {
0249:                            _isFieldInit = true;
0250:                            Value retVal = fieldSet.callMethod(env, this , name,
0251:                                    value);
0252:                            _isFieldInit = false;
0253:
0254:                            return retVal;
0255:                        }
0256:                    }
0257:                }
0258:
0259:                entry = createEntry(name);
0260:
0261:                Value oldValue = entry._value;
0262:
0263:                if (value instanceof  Var) {
0264:                    Var var = (Var) value;
0265:
0266:                    // for function return optimization
0267:                    var.setReference();
0268:
0269:                    entry._value = var;
0270:                } else if (oldValue instanceof  Var) {
0271:                    oldValue.set(value);
0272:                } else {
0273:                    entry._value = value;
0274:                }
0275:
0276:                return value;
0277:            }
0278:
0279:            /**
0280:             * Sets/adds field to this object.
0281:             */
0282:            @Override
0283:            public Value putThisField(Env env, StringValue name, Value value) {
0284:                Entry entry = getEntry(name);
0285:
0286:                if (entry == null) {
0287:                    Value oldValue = putFieldExt(env, name, value);
0288:
0289:                    if (oldValue != null)
0290:                        return oldValue;
0291:
0292:                    if (!_isFieldInit) {
0293:                        AbstractFunction fieldSet = _quercusClass.getFieldSet();
0294:
0295:                        if (fieldSet != null) {
0296:                            //php/09k7
0297:                            _isFieldInit = true;
0298:
0299:                            Value retVal = fieldSet.callMethod(env, this , name,
0300:                                    value);
0301:
0302:                            _isFieldInit = false;
0303:                            return retVal;
0304:                        }
0305:                    }
0306:                }
0307:
0308:                entry = createEntry(name);
0309:
0310:                Value oldValue = entry._value;
0311:
0312:                if (value instanceof  Var) {
0313:                    Var var = (Var) value;
0314:
0315:                    // for function return optimization
0316:                    var.setReference();
0317:
0318:                    entry._value = var;
0319:                } else if (oldValue instanceof  Var) {
0320:                    oldValue.set(value);
0321:                } else {
0322:                    entry._value = value;
0323:                }
0324:
0325:                return value;
0326:            }
0327:
0328:            protected Value putFieldExt(Env env, StringValue name, Value value) {
0329:                return null;
0330:            }
0331:
0332:            /**
0333:             * Adds a new value to the object.
0334:             */
0335:            @Override
0336:            public void initField(StringValue key, Value value) {
0337:                Entry entry = createEntry(key);
0338:
0339:                entry._value = value;
0340:            }
0341:
0342:            /**
0343:             * Removes a value.
0344:             */
0345:            @Override
0346:            public void unsetField(StringValue name) {
0347:                int hash = name.hashCode() & _hashMask;
0348:
0349:                for (Entry entry = _entries[hash]; entry != null; entry = entry._next) {
0350:                    if (name.equals(entry.getKey())) {
0351:                        Entry prev = entry._prev;
0352:                        Entry next = entry._next;
0353:
0354:                        if (prev != null)
0355:                            prev._next = next;
0356:                        else
0357:                            _entries[hash] = next;
0358:
0359:                        if (next != null)
0360:                            next._prev = prev;
0361:
0362:                        _size--;
0363:
0364:                        return;
0365:                    }
0366:                }
0367:            }
0368:
0369:            /**
0370:             * Gets a new value.
0371:             */
0372:            private Entry getEntry(StringValue name) {
0373:                int hash = name.hashCode() & _hashMask;
0374:
0375:                for (Entry entry = _entries[hash]; entry != null; entry = entry._next) {
0376:                    if (name.equals(entry._key))
0377:                        return entry;
0378:                }
0379:
0380:                return null;
0381:            }
0382:
0383:            /**
0384:             * Creates the entry for a key.
0385:             */
0386:            private Entry createEntry(StringValue name) {
0387:                int hash = name.hashCode() & _hashMask;
0388:
0389:                for (Entry entry = _entries[hash]; entry != null; entry = entry._next) {
0390:                    if (name.equals(entry._key))
0391:                        return entry;
0392:                }
0393:
0394:                _size++;
0395:
0396:                Entry newEntry = new Entry(name);
0397:                Entry next = _entries[hash];
0398:
0399:                if (next != null) {
0400:                    newEntry._next = next;
0401:                    next._prev = newEntry;
0402:                }
0403:
0404:                _entries[hash] = newEntry;
0405:
0406:                // XXX: possibly resize
0407:
0408:                return newEntry;
0409:            }
0410:
0411:            //
0412:            // array methods
0413:            //
0414:
0415:            /**
0416:             * Returns the array value with the given key.
0417:             */
0418:            @Override
0419:            public Value get(Value key) {
0420:                ArrayDelegate delegate = _quercusClass.getArrayDelegate();
0421:
0422:                // php/066q vs. php/0906
0423:                //return getField(null, key.toString());
0424:
0425:                if (delegate != null)
0426:                    return delegate.get(this , key);
0427:                else
0428:                    return super .get(key);
0429:            }
0430:
0431:            /**
0432:             * Sets the array value with the given key.
0433:             */
0434:            @Override
0435:            public Value put(Value key, Value value) {
0436:                // php/0d94
0437:                ArrayDelegate delegate = _quercusClass.getArrayDelegate();
0438:
0439:                if (delegate != null)
0440:                    return delegate.put(this , key, value);
0441:                else
0442:                    return super .put(key, value);
0443:            }
0444:
0445:            /**
0446:             * Appends a new array value
0447:             */
0448:            @Override
0449:            public Value put(Value value) {
0450:                // php/0d94
0451:                ArrayDelegate delegate = _quercusClass.getArrayDelegate();
0452:
0453:                if (delegate != null)
0454:                    return delegate.put(this , value);
0455:                else
0456:                    return super .put(value);
0457:            }
0458:
0459:            /**
0460:             * Unsets the array value
0461:             */
0462:            @Override
0463:            public Value remove(Value key) {
0464:                ArrayDelegate delegate = _quercusClass.getArrayDelegate();
0465:
0466:                if (delegate != null)
0467:                    return delegate.unset(this , key);
0468:                else
0469:                    return super .remove(key);
0470:            }
0471:
0472:            //
0473:            // Foreach/Traversable functions
0474:            //
0475:
0476:            /**
0477:             * Returns an iterator for the key => value pairs.
0478:             */
0479:            @Override
0480:            public Iterator<Map.Entry<Value, Value>> getIterator(Env env) {
0481:                TraversableDelegate delegate = _quercusClass
0482:                        .getTraversableDelegate();
0483:
0484:                if (delegate != null)
0485:                    return delegate.getIterator(env, this );
0486:
0487:                return new EntryIterator(_entries);
0488:            }
0489:
0490:            /**
0491:             * Returns an iterator for the keys.
0492:             */
0493:            @Override
0494:            public Iterator<Value> getKeyIterator(Env env) {
0495:                TraversableDelegate delegate = _quercusClass
0496:                        .getTraversableDelegate();
0497:
0498:                if (delegate != null)
0499:                    return delegate.getKeyIterator(env, this );
0500:
0501:                return new KeyIterator(_entries);
0502:            }
0503:
0504:            /**
0505:             * Returns an iterator for the values.
0506:             */
0507:            @Override
0508:            public Iterator<Value> getValueIterator(Env env) {
0509:                TraversableDelegate delegate = _quercusClass
0510:                        .getTraversableDelegate();
0511:
0512:                if (delegate != null)
0513:                    return delegate.getValueIterator(env, this );
0514:
0515:                return new ValueIterator(_entries);
0516:            }
0517:
0518:            //
0519:            // method calls
0520:            //
0521:
0522:            /**
0523:             * Finds the method name.
0524:             */
0525:            @Override
0526:            public AbstractFunction findFunction(String methodName) {
0527:                return _quercusClass.findFunction(methodName);
0528:            }
0529:
0530:            /**
0531:             * Evaluates a method.
0532:             */
0533:            @Override
0534:            public Value callMethod(Env env, int hash, char[] name,
0535:                    int nameLen, Expr[] args) {
0536:                AbstractFunction fun = _methodMap.get(hash, name, nameLen);
0537:
0538:                if (fun != null)
0539:                    return fun.callMethod(env, this , args);
0540:                else if (_quercusClass.getCall() != null) {
0541:                    Expr[] newArgs = new Expr[args.length + 1];
0542:                    newArgs[0] = new StringLiteralExpr(toMethod(name, nameLen));
0543:                    System.arraycopy(args, 0, newArgs, 1, args.length);
0544:
0545:                    return _quercusClass.getCall().callMethod(env, this ,
0546:                            newArgs);
0547:                } else
0548:                    return env.error(L.l("Call to undefined method {0}::{1}",
0549:                            getName(), toMethod(name, nameLen)));
0550:            }
0551:
0552:            /**
0553:             * Evaluates a method.
0554:             */
0555:            @Override
0556:            public Value callMethod(Env env, int hash, char[] name,
0557:                    int nameLen, Value[] args) {
0558:                AbstractFunction fun = _methodMap.get(hash, name, nameLen);
0559:
0560:                if (fun != null)
0561:                    return fun.callMethod(env, this , args);
0562:                else if ((fun = _quercusClass.getCall()) != null) {
0563:                    return fun.callMethod(env, this , env.createString(name,
0564:                            nameLen), new ArrayValueImpl(args));
0565:                } else
0566:                    return env.error(L.l("Call to undefined method {0}::{1}()",
0567:                            getName(), toMethod(name, nameLen)));
0568:            }
0569:
0570:            /**
0571:             * Evaluates a method.
0572:             */
0573:            @Override
0574:            public Value callMethod(Env env, int hash, char[] name, int nameLen) {
0575:                AbstractFunction fun = _methodMap.get(hash, name, nameLen);
0576:
0577:                if (fun != null)
0578:                    return fun.callMethod(env, this );
0579:                else if ((fun = _quercusClass.getCall()) != null) {
0580:                    return fun.callMethod(env, this , env.createString(name,
0581:                            nameLen), new ArrayValueImpl());
0582:                } else
0583:                    return env.error(L.l("Call to undefined method {0}::{1}()",
0584:                            getName(), toMethod(name, nameLen)));
0585:            }
0586:
0587:            /**
0588:             * Evaluates a method.
0589:             */
0590:            @Override
0591:            public Value callMethod(Env env, int hash, char[] name,
0592:                    int nameLen, Value a1) {
0593:                AbstractFunction fun = _methodMap.get(hash, name, nameLen);
0594:
0595:                if (fun != null)
0596:                    return fun.callMethod(env, this , a1);
0597:                else if ((fun = _quercusClass.getCall()) != null) {
0598:                    return fun.callMethod(env, this , env.createString(name,
0599:                            nameLen), new ArrayValueImpl().append(a1));
0600:                } else
0601:                    return env.error(L.l("Call to undefined method {0}::{1}()",
0602:                            getName(), toMethod(name, nameLen)));
0603:            }
0604:
0605:            /**
0606:             * Evaluates a method.
0607:             */
0608:            @Override
0609:            public Value callMethod(Env env, int hash, char[] name,
0610:                    int nameLen, Value a1, Value a2) {
0611:                AbstractFunction fun = _methodMap.get(hash, name, nameLen);
0612:
0613:                if (fun != null)
0614:                    return fun.callMethod(env, this , a1, a2);
0615:                else if ((fun = _quercusClass.getCall()) != null) {
0616:                    return fun.callMethod(env, this , env.createString(name,
0617:                            nameLen), new ArrayValueImpl().append(a1)
0618:                            .append(a2));
0619:                } else
0620:                    return env.error(L.l("Call to undefined method {0}::{1}()",
0621:                            getName(), toMethod(name, nameLen)));
0622:            }
0623:
0624:            /**
0625:             * calls the function.
0626:             */
0627:            @Override
0628:            public Value callMethod(Env env, int hash, char[] name,
0629:                    int nameLen, Value a1, Value a2, Value a3) {
0630:                AbstractFunction fun = _methodMap.get(hash, name, nameLen);
0631:
0632:                if (fun != null)
0633:                    return fun.callMethod(env, this , a1, a2, a3);
0634:                else if ((fun = _quercusClass.getCall()) != null) {
0635:                    return fun.callMethod(env, this , env.createString(name,
0636:                            nameLen), new ArrayValueImpl().append(a1)
0637:                            .append(a2).append(a3));
0638:                } else
0639:                    return env.error(L.l("Call to undefined method {0}::{1}()",
0640:                            getName(), toMethod(name, nameLen)));
0641:            }
0642:
0643:            /**
0644:             * calls the function.
0645:             */
0646:            @Override
0647:            public Value callMethod(Env env, int hash, char[] name,
0648:                    int nameLen, Value a1, Value a2, Value a3, Value a4) {
0649:                AbstractFunction fun = _methodMap.get(hash, name, nameLen);
0650:
0651:                if (fun != null)
0652:                    return fun.callMethod(env, this , a1, a2, a3, a4);
0653:                else if ((fun = _quercusClass.getCall()) != null) {
0654:                    return fun.callMethod(env, this , env.createString(name,
0655:                            nameLen), new ArrayValueImpl().append(a1)
0656:                            .append(a2).append(a3).append(a4));
0657:                } else
0658:                    return env.error(L.l("Call to undefined method {0}::{1}()",
0659:                            getName(), toMethod(name, nameLen)));
0660:            }
0661:
0662:            /**
0663:             * calls the function.
0664:             */
0665:            @Override
0666:            public Value callMethod(Env env, int hash, char[] name,
0667:                    int nameLen, Value a1, Value a2, Value a3, Value a4,
0668:                    Value a5) {
0669:                AbstractFunction fun = _methodMap.get(hash, name, nameLen);
0670:
0671:                if (fun != null)
0672:                    return fun.callMethod(env, this , a1, a2, a3, a4, a5);
0673:                else if ((fun = _quercusClass.getCall()) != null) {
0674:                    return fun.callMethod(env, this , env.createString(name,
0675:                            nameLen), new ArrayValueImpl().append(a1)
0676:                            .append(a2).append(a3).append(a4).append(a5));
0677:                } else
0678:                    return env.error(L.l("Call to undefined method {0}::{1}()",
0679:                            getName(), toMethod(name, nameLen)));
0680:            }
0681:
0682:            /**
0683:             * Evaluates a method.
0684:             */
0685:            @Override
0686:            public Value callMethodRef(Env env, int hash, char[] name,
0687:                    int nameLen, Expr[] args) {
0688:                return _quercusClass.callMethodRef(env, this , hash, name,
0689:                        nameLen, args);
0690:            }
0691:
0692:            /**
0693:             * Evaluates a method.
0694:             */
0695:            @Override
0696:            public Value callMethodRef(Env env, int hash, char[] name,
0697:                    int nameLen, Value[] args) {
0698:                AbstractFunction fun = _methodMap.get(hash, name, nameLen);
0699:
0700:                if (fun != null)
0701:                    return fun.callMethodRef(env, this , args);
0702:                else if ((fun = _quercusClass.getCall()) != null) {
0703:                    return fun.callMethodRef(env, this , env.createString(name,
0704:                            nameLen), new ArrayValueImpl(args));
0705:                } else
0706:                    return env.error(L.l("Call to undefined method {0}::{1}()",
0707:                            getName(), toMethod(name, nameLen)));
0708:            }
0709:
0710:            /**
0711:             * Evaluates a method.
0712:             */
0713:            @Override
0714:            public Value callMethodRef(Env env, int hash, char[] name,
0715:                    int nameLen) {
0716:                AbstractFunction fun = _methodMap.get(hash, name, nameLen);
0717:
0718:                if (fun != null)
0719:                    return fun.callMethodRef(env, this );
0720:                else if ((fun = _quercusClass.getCall()) != null) {
0721:                    return fun.callMethodRef(env, this , env.createString(name,
0722:                            nameLen), new ArrayValueImpl());
0723:                } else
0724:                    return env.error(L.l("Call to undefined method {0}::{1}()",
0725:                            getName(), toMethod(name, nameLen)));
0726:            }
0727:
0728:            /**
0729:             * Evaluates a method.
0730:             */
0731:            @Override
0732:            public Value callMethodRef(Env env, int hash, char[] name,
0733:                    int nameLen, Value a1) {
0734:                AbstractFunction fun = _methodMap.get(hash, name, nameLen);
0735:
0736:                if (fun != null)
0737:                    return fun.callMethodRef(env, this , a1);
0738:                else if ((fun = _quercusClass.getCall()) != null) {
0739:                    return fun.callMethodRef(env, this , env.createString(name,
0740:                            nameLen), new ArrayValueImpl().append(a1));
0741:                } else
0742:                    return env.error(L.l("Call to undefined method {0}::{1}()",
0743:                            getName(), toMethod(name, nameLen)));
0744:            }
0745:
0746:            /**
0747:             * Evaluates a method.
0748:             */
0749:            @Override
0750:            public Value callMethodRef(Env env, int hash, char[] name,
0751:                    int nameLen, Value a1, Value a2) {
0752:                AbstractFunction fun = _methodMap.get(hash, name, nameLen);
0753:
0754:                if (fun != null)
0755:                    return fun.callMethodRef(env, this , a1, a2);
0756:                else if ((fun = _quercusClass.getCall()) != null) {
0757:                    return fun.callMethodRef(env, this , env.createString(name,
0758:                            nameLen), new ArrayValueImpl().append(a1)
0759:                            .append(a2));
0760:                } else
0761:                    return env.error(L.l("Call to undefined method {0}::{1}()",
0762:                            getName(), toMethod(name, nameLen)));
0763:            }
0764:
0765:            /**
0766:             * Evaluates a method.
0767:             */
0768:            @Override
0769:            public Value callMethodRef(Env env, int hash, char[] name,
0770:                    int nameLen, Value a1, Value a2, Value a3) {
0771:                AbstractFunction fun = _methodMap.get(hash, name, nameLen);
0772:
0773:                if (fun != null)
0774:                    return fun.callMethodRef(env, this , a1, a2, a3);
0775:                else if ((fun = _quercusClass.getCall()) != null) {
0776:                    return fun.callMethodRef(env, this , env.createString(name,
0777:                            nameLen), new ArrayValueImpl().append(a1)
0778:                            .append(a2).append(a3));
0779:                } else
0780:                    return env.error(L.l("Call to undefined method {0}::{1}()",
0781:                            getName(), toMethod(name, nameLen)));
0782:            }
0783:
0784:            /**
0785:             * Evaluates a method.
0786:             */
0787:            @Override
0788:            public Value callMethodRef(Env env, int hash, char[] name,
0789:                    int nameLen, Value a1, Value a2, Value a3, Value a4) {
0790:                AbstractFunction fun = _methodMap.get(hash, name, nameLen);
0791:
0792:                if (fun != null)
0793:                    return fun.callMethodRef(env, this , a1, a2, a3, a4);
0794:                else if ((fun = _quercusClass.getCall()) != null) {
0795:                    return fun.callMethodRef(env, this , env.createString(name,
0796:                            nameLen), new ArrayValueImpl().append(a1)
0797:                            .append(a2).append(a3).append(a4));
0798:                } else
0799:                    return env.error(L.l("Call to undefined method {0}::{1}()",
0800:                            getName(), toMethod(name, nameLen)));
0801:            }
0802:
0803:            /**
0804:             * Evaluates a method.
0805:             */
0806:            @Override
0807:            public Value callMethodRef(Env env, int hash, char[] name,
0808:                    int nameLen, Value a1, Value a2, Value a3, Value a4,
0809:                    Value a5) {
0810:                AbstractFunction fun = _methodMap.get(hash, name, nameLen);
0811:
0812:                if (fun != null)
0813:                    return fun.callMethodRef(env, this , a1, a2, a3, a4, a5);
0814:                else if ((fun = _quercusClass.getCall()) != null) {
0815:                    return fun.callMethodRef(env, this , env.createString(name,
0816:                            nameLen), new ArrayValueImpl().append(a1)
0817:                            .append(a2).append(a3).append(a4).append(a5));
0818:                } else
0819:                    return env.error(L.l("Call to undefined method {0}::{1}()",
0820:                            getName(), toMethod(name, nameLen)));
0821:            }
0822:
0823:            /**
0824:             * Evaluates a method.
0825:             */
0826:            @Override
0827:            public Value callClassMethod(Env env, AbstractFunction fun,
0828:                    Value[] args) {
0829:                return fun.callMethod(env, this , args);
0830:            }
0831:
0832:            /**
0833:             * Returns the value for the variable, creating an object if the var
0834:             * is unset.
0835:             */
0836:            @Override
0837:            public Value getObject(Env env) {
0838:                return this ;
0839:            }
0840:
0841:            @Override
0842:            public Value getObject(Env env, Value index) {
0843:                // php/3d92
0844:
0845:                env.error(L.l("Can't use object '{0}' as array", getName()));
0846:
0847:                return NullValue.NULL;
0848:            }
0849:
0850:            /**
0851:             * Copy for assignment.
0852:             */
0853:            @Override
0854:            public Value copy() {
0855:                return this ;
0856:            }
0857:
0858:            /**
0859:             * Copy for serialization
0860:             */
0861:            @Override
0862:            public Value copy(Env env, IdentityHashMap<Value, Value> map) {
0863:                Value oldValue = map.get(this );
0864:
0865:                if (oldValue != null)
0866:                    return oldValue;
0867:
0868:                // XXX:
0869:                // return new ObjectExtValue(env, map, _cl, getArray());
0870:
0871:                return this ;
0872:            }
0873:
0874:            /**
0875:             * Copy for serialization
0876:             */
0877:            @Override
0878:            public Value copyTree(Env env) {
0879:                // XXX:
0880:                // return new ObjectExtValue(env, map, _cl, getArray());
0881:
0882:                return this ;
0883:            }
0884:
0885:            /**
0886:             * Clone the object
0887:             */
0888:            @Override
0889:            public Value clone() {
0890:                ObjectExtValue newObject = new ObjectExtValue(_quercusClass);
0891:
0892:                for (Map.Entry<Value, Value> entry : entrySet()) {
0893:                    newObject.putThisField(null, (StringValue) entry.getKey(),
0894:                            entry.getValue());
0895:                }
0896:
0897:                return newObject;
0898:            }
0899:
0900:            // XXX: need to check the other copy, e.g. for sessions
0901:
0902:            /**
0903:             * Serializes the value.
0904:             */
0905:            @Override
0906:            public void serialize(StringBuilder sb) {
0907:                sb.append("O:");
0908:                sb.append(_quercusClass.getName().length());
0909:                sb.append(":\"");
0910:                sb.append(_quercusClass.getName());
0911:                sb.append("\":");
0912:                sb.append(getSize());
0913:                sb.append(":{");
0914:
0915:                for (Map.Entry<Value, Value> entry : entrySet()) {
0916:                    Value key = entry.getKey();
0917:
0918:                    sb.append("s:");
0919:                    sb.append(key.length());
0920:                    sb.append(":\"");
0921:                    sb.append(key);
0922:                    sb.append("\";");
0923:
0924:                    entry.getValue().serialize(sb);
0925:                }
0926:
0927:                sb.append("}");
0928:            }
0929:
0930:            /**
0931:             * Converts to a string.
0932:             * @param env
0933:             */
0934:            @Override
0935:            public StringValue toString(Env env) {
0936:                AbstractFunction fun = _quercusClass.findFunction("__toString");
0937:
0938:                if (fun != null)
0939:                    return fun.callMethod(env, this , new Expr[0])
0940:                            .toStringValue();
0941:                else
0942:                    return env.createString(_quercusClass.getName() + "[]");
0943:            }
0944:
0945:            /**
0946:             * Converts to a string.
0947:             * @param env
0948:             */
0949:            @Override
0950:            public void print(Env env) {
0951:                env.print(toString(env));
0952:            }
0953:
0954:            /**
0955:             * Converts to an array.
0956:             */
0957:            @Override
0958:            public Value toArray() {
0959:                ArrayValue array = new ArrayValueImpl();
0960:
0961:                for (Map.Entry<Value, Value> entry : entrySet()) {
0962:                    array.put(entry.getKey(), entry.getValue());
0963:                }
0964:
0965:                return array;
0966:            }
0967:
0968:            /**
0969:             * Converts to an object.
0970:             */
0971:            @Override
0972:            public Value toObject(Env env) {
0973:                return this ;
0974:            }
0975:
0976:            /**
0977:             * Converts to an object.
0978:             */
0979:            @Override
0980:            public Object toJavaObject() {
0981:                return this ;
0982:            }
0983:
0984:            @Override
0985:            public Set<? extends Map.Entry<Value, Value>> entrySet() {
0986:                return new EntrySet();
0987:            }
0988:
0989:            /**
0990:             * Returns a Set of entries, sorted by key.
0991:             */
0992:            public Set<? extends Map.Entry<Value, Value>> sortedEntrySet() {
0993:                return new TreeSet<Map.Entry<Value, Value>>(entrySet());
0994:            }
0995:
0996:            //
0997:            // debugging
0998:            //
0999:
1000:            public void varDumpImpl(Env env, WriteStream out, int depth,
1001:                    IdentityHashMap<Value, String> valueSet) throws IOException {
1002:                // XXX: push up to super, and use varDumpObject
1003:                out.println("object(" + getName() + ") (" + getSize() + ") {");
1004:
1005:                for (Map.Entry<Value, Value> mapEntry : sortedEntrySet()) {
1006:                    ObjectExtValue.Entry entry = (ObjectExtValue.Entry) mapEntry;
1007:
1008:                    entry.varDumpImpl(env, out, depth + 1, valueSet);
1009:                }
1010:
1011:                printDepth(out, 2 * depth);
1012:
1013:                out.print("}");
1014:            }
1015:
1016:            @Override
1017:            protected void printRImpl(Env env, WriteStream out, int depth,
1018:                    IdentityHashMap<Value, String> valueSet) throws IOException {
1019:                out.print(getName());
1020:                out.print(' ');
1021:                out.println("Object");
1022:                printDepth(out, 4 * depth);
1023:                out.println("(");
1024:
1025:                for (Map.Entry<Value, Value> mapEntry : sortedEntrySet()) {
1026:                    ObjectExtValue.Entry entry = (ObjectExtValue.Entry) mapEntry;
1027:
1028:                    entry.printRImpl(env, out, depth + 1, valueSet);
1029:                }
1030:
1031:                printDepth(out, 4 * depth);
1032:                out.println(")");
1033:            }
1034:
1035:            //
1036:            // Java Serialization
1037:            //
1038:
1039:            private void writeObject(ObjectOutputStream out) throws IOException {
1040:                out.writeObject(_quercusClass.getName());
1041:
1042:                out.writeInt(_size);
1043:
1044:                for (Map.Entry<Value, Value> entry : entrySet()) {
1045:                    out.writeObject(entry.getKey());
1046:                    out.writeObject(entry.getValue());
1047:                }
1048:            }
1049:
1050:            private void readObject(ObjectInputStream in)
1051:                    throws ClassNotFoundException, IOException {
1052:                Env env = Env.getInstance();
1053:                String name = (String) in.readObject();
1054:
1055:                QuercusClass cl = env.findClass(name);
1056:
1057:                init();
1058:
1059:                if (cl != null) {
1060:                    setQuercusClass(cl);
1061:                } else {
1062:                    cl = env.getQuercus().getStdClass();
1063:
1064:                    setQuercusClass(cl);
1065:
1066:                    putThisField(
1067:                            env,
1068:                            env
1069:                                    .createString("__Quercus_Class_Definition_Not_Found"),
1070:                            env.createString(name));
1071:                }
1072:
1073:                int size = in.readInt();
1074:
1075:                for (int i = 0; i < size; i++) {
1076:                    putThisField(env, (StringValue) in.readObject(), (Value) in
1077:                            .readObject());
1078:                }
1079:            }
1080:
1081:            private static String toMethod(char[] key, int keyLength) {
1082:                return new String(key, 0, keyLength);
1083:            }
1084:
1085:            @Override
1086:            public String toString() {
1087:                return "ObjectExtValue@" + System.identityHashCode(this ) + "["
1088:                        + _quercusClass.getName() + "]";
1089:            }
1090:
1091:            public class EntrySet extends AbstractSet<Map.Entry<Value, Value>> {
1092:                EntrySet() {
1093:                }
1094:
1095:                @Override
1096:                public int size() {
1097:                    return ObjectExtValue.this .getSize();
1098:                }
1099:
1100:                @Override
1101:                public Iterator<Map.Entry<Value, Value>> iterator() {
1102:                    return new EntryIterator(ObjectExtValue.this ._entries);
1103:                }
1104:            }
1105:
1106:            public static class EntryIterator implements 
1107:                    Iterator<Map.Entry<Value, Value>> {
1108:                private final Entry[] _list;
1109:                private int _index;
1110:                private Entry _entry;
1111:
1112:                EntryIterator(Entry[] list) {
1113:                    _list = list;
1114:                }
1115:
1116:                public boolean hasNext() {
1117:                    if (_entry != null)
1118:                        return true;
1119:
1120:                    for (; _index < _list.length && _list[_index] == null; _index++) {
1121:                    }
1122:
1123:                    return _index < _list.length;
1124:                }
1125:
1126:                public Map.Entry<Value, Value> next() {
1127:                    if (_entry != null) {
1128:                        Entry entry = _entry;
1129:                        _entry = entry._next;
1130:
1131:                        return entry;
1132:                    }
1133:
1134:                    for (; _index < _list.length && _list[_index] == null; _index++) {
1135:                    }
1136:
1137:                    if (_list.length <= _index)
1138:                        return null;
1139:
1140:                    Entry entry = _list[_index++];
1141:                    _entry = entry._next;
1142:
1143:                    return entry;
1144:                }
1145:
1146:                public void remove() {
1147:                    throw new UnsupportedOperationException();
1148:                }
1149:            }
1150:
1151:            public static class ValueIterator implements  Iterator<Value> {
1152:                private final Entry[] _list;
1153:                private int _index;
1154:                private Entry _entry;
1155:
1156:                ValueIterator(Entry[] list) {
1157:                    _list = list;
1158:                }
1159:
1160:                public boolean hasNext() {
1161:                    if (_entry != null)
1162:                        return true;
1163:
1164:                    for (; _index < _list.length && _list[_index] == null; _index++) {
1165:                    }
1166:
1167:                    return _index < _list.length;
1168:                }
1169:
1170:                public Value next() {
1171:                    if (_entry != null) {
1172:                        Entry entry = _entry;
1173:                        _entry = entry._next;
1174:
1175:                        return entry._value;
1176:                    }
1177:
1178:                    for (; _index < _list.length && _list[_index] == null; _index++) {
1179:                    }
1180:
1181:                    if (_list.length <= _index)
1182:                        return null;
1183:
1184:                    Entry entry = _list[_index++];
1185:                    _entry = entry._next;
1186:
1187:                    return entry._value;
1188:                }
1189:
1190:                public void remove() {
1191:                    throw new UnsupportedOperationException();
1192:                }
1193:            }
1194:
1195:            public static class KeyIterator implements  Iterator<Value> {
1196:                private final Entry[] _list;
1197:                private int _index;
1198:                private Entry _entry;
1199:
1200:                KeyIterator(Entry[] list) {
1201:                    _list = list;
1202:                }
1203:
1204:                public boolean hasNext() {
1205:                    if (_entry != null)
1206:                        return true;
1207:
1208:                    for (; _index < _list.length && _list[_index] == null; _index++) {
1209:                    }
1210:
1211:                    return _index < _list.length;
1212:                }
1213:
1214:                public Value next() {
1215:                    if (_entry != null) {
1216:                        Entry entry = _entry;
1217:                        _entry = entry._next;
1218:
1219:                        return entry._key;
1220:                    }
1221:
1222:                    for (; _index < _list.length && _list[_index] == null; _index++) {
1223:                    }
1224:
1225:                    if (_list.length <= _index)
1226:                        return null;
1227:
1228:                    Entry entry = _list[_index++];
1229:                    _entry = entry._next;
1230:
1231:                    return entry._key;
1232:                }
1233:
1234:                public void remove() {
1235:                    throw new UnsupportedOperationException();
1236:                }
1237:            }
1238:
1239:            public final static class Entry implements  Map.Entry<Value, Value>,
1240:                    Comparable<Map.Entry<Value, Value>> {
1241:                private final StringValue _key;
1242:                private Value _value;
1243:
1244:                Entry _prev;
1245:                Entry _next;
1246:
1247:                public Entry(StringValue key) {
1248:                    _key = key;
1249:                    _value = NullValue.NULL;
1250:                }
1251:
1252:                public Entry(StringValue key, Value value) {
1253:                    _key = key;
1254:                    _value = value;
1255:                }
1256:
1257:                public Value getValue() {
1258:                    return _value.toValue();
1259:                }
1260:
1261:                public Value getKey() {
1262:                    return _key;
1263:                }
1264:
1265:                public Value toValue() {
1266:                    // The value may be a var
1267:                    // XXX: need test
1268:                    return _value.toValue();
1269:                }
1270:
1271:                /**
1272:                 * Argument used/declared as a ref.
1273:                 */
1274:                public Var toRefVar() {
1275:                    Var var = _value.toRefVar();
1276:
1277:                    _value = var;
1278:
1279:                    return var;
1280:                }
1281:
1282:                /**
1283:                 * Converts to an argument value.
1284:                 */
1285:                public Value toArgValue() {
1286:                    return _value.toValue();
1287:                }
1288:
1289:                public Value setValue(Value value) {
1290:                    Value oldValue = toValue();
1291:
1292:                    _value = value;
1293:
1294:                    return oldValue;
1295:                }
1296:
1297:                /**
1298:                 * Converts to a variable reference (for function arguments)
1299:                 */
1300:                public Value toRef() {
1301:                    Value value = _value;
1302:
1303:                    if (value instanceof  Var)
1304:                        return new RefVar((Var) value);
1305:                    else {
1306:                        Var var = new Var(_value);
1307:
1308:                        _value = var;
1309:
1310:                        return new RefVar(var);
1311:                    }
1312:                }
1313:
1314:                /**
1315:                 * Converts to a variable reference (for function  arguments)
1316:                 */
1317:                public Value toArgRef() {
1318:                    Value value = _value;
1319:
1320:                    if (value instanceof  Var)
1321:                        return new RefVar((Var) value);
1322:                    else {
1323:                        Var var = new Var(_value);
1324:
1325:                        _value = var;
1326:
1327:                        return new RefVar(var);
1328:                    }
1329:                }
1330:
1331:                public Value toArg() {
1332:                    Value value = _value;
1333:
1334:                    if (value instanceof  Var)
1335:                        return value;
1336:                    else {
1337:                        Var var = new Var(_value);
1338:
1339:                        _value = var;
1340:
1341:                        return var;
1342:                    }
1343:                }
1344:
1345:                public int compareTo(Map.Entry<Value, Value> other) {
1346:                    if (other == null)
1347:                        return 1;
1348:
1349:                    Value this Key = getKey();
1350:                    Value otherKey = other.getKey();
1351:
1352:                    if (this Key == null)
1353:                        return otherKey == null ? 0 : -1;
1354:
1355:                    if (otherKey == null)
1356:                        return 1;
1357:
1358:                    return this Key.cmp(otherKey);
1359:                }
1360:
1361:                public void varDumpImpl(Env env, WriteStream out, int depth,
1362:                        IdentityHashMap<Value, String> valueSet)
1363:                        throws IOException {
1364:                    printDepth(out, 2 * depth);
1365:                    out.println("[\"" + getKey() + "\"]=>");
1366:
1367:                    printDepth(out, 2 * depth);
1368:
1369:                    _value.varDump(env, out, depth, valueSet);
1370:
1371:                    out.println();
1372:                }
1373:
1374:                protected void printRImpl(Env env, WriteStream out, int depth,
1375:                        IdentityHashMap<Value, String> valueSet)
1376:                        throws IOException {
1377:                    printDepth(out, 4 * depth);
1378:                    out.print("[" + getKey() + "] => ");
1379:
1380:                    _value.printR(env, out, depth + 1, valueSet);
1381:
1382:                    out.println();
1383:                }
1384:
1385:                private void printDepth(WriteStream out, int depth)
1386:                        throws java.io.IOException {
1387:                    for (int i = 0; i < depth; i++)
1388:                        out.print(' ');
1389:                }
1390:
1391:                @Override
1392:                public String toString() {
1393:                    return "ObjectExtValue.Entry[" + getKey() + "]";
1394:                }
1395:            }
1396:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.