Source Code Cross Referenced for PropertyEntry.java in  » J2EE » fleXive » com » flexive » core » search » 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 » J2EE » fleXive » com.flexive.core.search 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        /***************************************************************
002:         *  This file is part of the [fleXive](R) project.
003:         *
004:         *  Copyright (c) 1999-2007
005:         *  UCS - unique computing solutions gmbh (http://www.ucs.at)
006:         *  All rights reserved
007:         *
008:         *  The [fleXive](R) project is free software; you can redistribute
009:         *  it and/or modify it under the terms of the GNU General Public
010:         *  License as published by the Free Software Foundation;
011:         *  either version 2 of the License, or (at your option) any
012:         *  later version.
013:         *
014:         *  The GNU General Public License can be found at
015:         *  http://www.gnu.org/copyleft/gpl.html.
016:         *  A copy is found in the textfile GPL.txt and important notices to the
017:         *  license from the author are found in LICENSE.txt distributed with
018:         *  these libraries.
019:         *
020:         *  This library is distributed in the hope that it will be useful,
021:         *  but WITHOUT ANY WARRANTY; without even the implied warranty of
022:         *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
023:         *  GNU General Public License for more details.
024:         *
025:         *  For further information about UCS - unique computing solutions gmbh,
026:         *  please see the company website: http://www.ucs.at
027:         *
028:         *  For further information about [fleXive](R), please see the
029:         *  project website: http://www.flexive.org
030:         *
031:         *
032:         *  This copyright notice MUST APPEAR in all copies of the file!
033:         ***************************************************************/package com.flexive.core.search;
034:
035:        import com.flexive.shared.structure.*;
036:        import com.flexive.shared.exceptions.FxSqlSearchException;
037:        import com.flexive.shared.exceptions.FxRuntimeException;
038:        import com.flexive.shared.exceptions.FxNotFoundException;
039:        import com.flexive.shared.value.*;
040:        import com.flexive.shared.FxLanguage;
041:        import com.flexive.shared.CacheAdmin;
042:        import com.flexive.shared.search.FxPaths;
043:        import com.flexive.shared.content.FxPK;
044:        import com.flexive.core.DatabaseConst;
045:        import com.flexive.core.storage.ContentStorage;
046:        import com.flexive.sqlParser.Property;
047:        import org.apache.commons.lang.StringUtils;
048:        import org.apache.commons.logging.Log;
049:        import org.apache.commons.logging.LogFactory;
050:
051:        import java.sql.ResultSet;
052:        import java.sql.Timestamp;
053:        import java.sql.SQLException;
054:        import java.util.Date;
055:
056:        /**
057:         * <p>
058:         * A single entry of the property resolver, i.e. a selected property. A new entry is instantiated for every
059:         * column of a search query, it also stores context information like the column index in the SQL result set.
060:         * </p>
061:         * <p>
062:         * To create a new property entry type (e.g. a new virtual property), you have to:
063:         * <ol>
064:         * <li>Register a new {@link PropertyEntry.Type} that matches the property name</li>
065:         * <li>Create a new subclass of {@link PropertyEntry} that selects the columns and specifies
066:         * a method to read the value from the result set</li>
067:         * <li>Extend the factory method {@link PropertyEntry.Type#createEntry()}</li>
068:         * <li>Only if you need database-specific procedure calls: extend the {@link DataSelector}
069:         * implementation</li>
070:         * </ol>
071:         * </p>
072:         *
073:         * @author Gregor Schober (gregor.schober@flexive.com), UCS - unique computing solutions gmbh (http://www.ucs.at)
074:         * @author Daniel Lichtenberger (daniel.lichtenberger@flexive.com), UCS - unique computing solutions gmbh (http://www.ucs.at)
075:         * @version $Rev$
076:         */
077:        public class PropertyEntry {
078:            private static final transient Log LOG = LogFactory
079:                    .getLog(PropertyEntry.class);
080:
081:            /**
082:             * Property entry types. A type is either a generic property selector (e.g. {@link #PROPERTY_REF}),
083:             * or a custom resolver like the primary key or tree path "virtual" properties.
084:             */
085:            public static enum Type {
086:                /**
087:                 * A common property reference, e.g. co.caption.
088:                 */
089:                PROPERTY_REF(null),
090:                /**
091:                 * A primary key (@pk) column.
092:                 */
093:                PK("@pk"),
094:
095:                /**
096:                 * A tree node path (@path) column.
097:                 */
098:                PATH("@path"),
099:
100:                /**
101:                 * A tree node position (@node_position) column.
102:                 */
103:                NODE_POSITION("@node_position");
104:
105:                private final String propertyName;
106:
107:                Type(String propertyName) {
108:                    this .propertyName = propertyName;
109:                }
110:
111:                /**
112:                 * Returns the property name this type applies for. If it is a generic type
113:                 * (i.e. {@link #PROPERTY_REF}, this method returns null.
114:                 *
115:                 * @return the property name this type applies for
116:                 */
117:                public String getPropertyName() {
118:                    return propertyName;
119:                }
120:
121:                /**
122:                 * Returns true if this type matches the given property name (e.g. "@pk").
123:                 * For generic types (i.e. {@link #PROPERTY_REF}), this method always returns false.
124:                 *
125:                 * @param name the property name to be matched
126:                 * @return true if this type matches the given property name (e.g. "@pk").
127:                 */
128:                public boolean matchesProperty(String name) {
129:                    return StringUtils.equalsIgnoreCase(propertyName, name);
130:                }
131:
132:                /**
133:                 * Create a new {@link PropertyEntry} instance for this property type. Does not
134:                 * work for generic entries (i.e. {@link #PROPERTY_REF}), these have to be created
135:                 * manually by creating a new instance of the generic {@link PropertyEntry} class.
136:                 *
137:                 * @return a new {@link PropertyEntry} instance for this property type.
138:                 */
139:                public PropertyEntry createEntry() {
140:                    switch (this ) {
141:                    case PK:
142:                        return new PkEntry();
143:                    case NODE_POSITION:
144:                        return new NodePositionEntry();
145:                    case PATH:
146:                        return new PathEntry();
147:                    case PROPERTY_REF:
148:                        throw new FxSqlSearchException(LOG,
149:                                "ex.sqlSearch.entry.virtual")
150:                                .asRuntimeException();
151:                    default:
152:                        throw new IllegalStateException();
153:                    }
154:                }
155:            }
156:
157:            /**
158:             * The primary key resolver (@pk)
159:             */
160:            private static class PkEntry extends PropertyEntry {
161:                private PkEntry() {
162:                    super (Type.PK, PropertyResolver.Table.T_CONTENT,
163:                            new String[] { "ID", "VERSION" }, null, false, null);
164:                }
165:
166:                @Override
167:                public Object getResultValue(ResultSet rs, FxLanguage language)
168:                        throws FxSqlSearchException {
169:                    try {
170:                        final long id = rs.getLong(positionInResultSet);
171:                        final int ver = rs.getInt(positionInResultSet + 1);
172:                        return new FxPK(id, ver);
173:                    } catch (SQLException e) {
174:                        throw new FxSqlSearchException(LOG, e);
175:                    }
176:                }
177:            }
178:
179:            /**
180:             * The tree path resolver (@path)
181:             */
182:            private static class PathEntry extends PropertyEntry {
183:                private PathEntry() {
184:                    super (Type.PATH, PropertyResolver.Table.T_CONTENT,
185:                            new String[] { "" }, // select one column (function will be inserted by DB adapter)
186:                            null, false, null);
187:                }
188:
189:                @Override
190:                public Object getResultValue(ResultSet rs, FxLanguage language)
191:                        throws FxSqlSearchException {
192:                    try {
193:                        return new FxPaths(rs.getString(positionInResultSet));
194:                    } catch (SQLException e) {
195:                        throw new FxSqlSearchException(LOG, e);
196:                    }
197:                }
198:            }
199:
200:            /**
201:             * The tree node position resolver (@node_position)
202:             */
203:            private static class NodePositionEntry extends PropertyEntry {
204:                private NodePositionEntry() {
205:                    super (Type.NODE_POSITION, PropertyResolver.Table.T_CONTENT,
206:                            new String[] { "" }, // select one column (function will be inserted by DB adapter)
207:                            null, false, FxDataType.Number);
208:                }
209:
210:                @Override
211:                public Object getResultValue(ResultSet rs, FxLanguage language)
212:                        throws FxSqlSearchException {
213:                    try {
214:                        return rs.getLong(positionInResultSet);
215:                    } catch (SQLException e) {
216:                        throw new FxSqlSearchException(LOG, e);
217:                    }
218:                }
219:            }
220:
221:            protected final String[] readColumns;
222:            protected final String filterColumn;
223:            protected final String tableName;
224:            protected final FxProperty property;
225:            protected final PropertyResolver.Table tbl;
226:            protected final Type type;
227:            protected final boolean multilanguage;
228:            protected int positionInResultSet = -1;
229:            protected FxPropertyAssignment assignment;
230:            protected FxDataType overrideDataType;
231:
232:            /**
233:             * Create a new instance based on the given (search) property.
234:             *
235:             * @param searchProperty the search property
236:             * @param storage        the storage instance
237:             * @param ignoreCase     whether case should be ignored for this column
238:             * @throws FxSqlSearchException if the entry could not be created
239:             */
240:            public PropertyEntry(Property searchProperty,
241:                    ContentStorage storage, boolean ignoreCase)
242:                    throws FxSqlSearchException {
243:                this .type = Type.PROPERTY_REF;
244:
245:                if (searchProperty.isAssignment()) {
246:                    try {
247:                        if (searchProperty.getPropertyName().indexOf('/') > 0) {
248:                            //XPath
249:                            this .assignment = (FxPropertyAssignment) CacheAdmin
250:                                    .getEnvironment().getAssignment(
251:                                            searchProperty.getPropertyName());
252:                        } else {
253:                            //#<id>
254:                            this .assignment = (FxPropertyAssignment) CacheAdmin
255:                                    .getEnvironment().getAssignment(
256:                                            Long.valueOf(searchProperty
257:                                                    .getPropertyName()
258:                                                    .substring(1)));
259:                        }
260:                    } catch (ClassCastException ce) {
261:                        throw new FxSqlSearchException(LOG, ce,
262:                                "ex.sqlSearch.query.unknownAssignment",
263:                                searchProperty.getPropertyName());
264:                    } catch (FxRuntimeException e) {
265:                        if (e.getConverted() instanceof  FxNotFoundException) {
266:                            throw new FxSqlSearchException(LOG, e,
267:                                    "ex.sqlSearch.query.unknownAssignment",
268:                                    searchProperty.getPropertyName());
269:                        } else {
270:                            throw new FxSqlSearchException(
271:                                    LOG,
272:                                    e,
273:                                    "ex.sqlSearch.query.failedToResolveAssignment",
274:                                    searchProperty.getPropertyName(), e
275:                                            .getMessage());
276:                        }
277:                    }
278:                    this .property = assignment.getProperty();
279:                } else {
280:                    this .assignment = null;
281:                    this .property = CacheAdmin.getEnvironment().getProperty(
282:                            searchProperty.getPropertyName());
283:                }
284:
285:                this .readColumns = storage.getColumns(this .property);
286:                String fcol = ignoreCase ? storage
287:                        .getUppercaseColumn(this .property)
288:                        : this .readColumns[0];
289:                if (fcol == null) {
290:                    fcol = this .readColumns == null ? null
291:                            : this .readColumns[0];
292:                }
293:                this .filterColumn = fcol;
294:
295:                if (this .filterColumn == null) {
296:                    throw new FxSqlSearchException(
297:                            LOG,
298:                            "ex.sqlSearch.init.propertyDoesNotHaveColumnMapping",
299:                            searchProperty.getPropertyName());
300:                }
301:
302:                this .tableName = storage.getTableName(this .property);
303:                if (this .tableName.equalsIgnoreCase(DatabaseConst.TBL_CONTENT)) {
304:                    this .tbl = PropertyResolver.Table.T_CONTENT;
305:                } else if (this .tableName
306:                        .equalsIgnoreCase(DatabaseConst.TBL_CONTENT_DATA)) {
307:                    this .tbl = PropertyResolver.Table.T_CONTENT_DATA;
308:                } else {
309:                    throw new FxSqlSearchException(LOG,
310:                            "ex.sqlSearch.err.unknownPropertyTable",
311:                            searchProperty, this .tableName);
312:                }
313:                this .multilanguage = this .property.isMultiLang();
314:            }
315:
316:            protected PropertyEntry(Type type, PropertyResolver.Table tbl,
317:                    String[] readColumns, String filterColumn,
318:                    boolean multilanguage, FxDataType overrideDataType) {
319:                this .readColumns = readColumns;
320:                this .filterColumn = filterColumn;
321:                this .tbl = tbl;
322:                this .type = type;
323:                this .multilanguage = multilanguage;
324:                this .overrideDataType = overrideDataType;
325:                this .property = null;
326:                this .tableName = null;
327:            }
328:
329:            /**
330:             * Return the result value of this property entry in a given result set.
331:             *
332:             * @param rs       the SQL result set
333:             * @param language the result language
334:             * @return the value of this property (column) in the result set
335:             * @throws FxSqlSearchException if the database cannot read the value
336:             */
337:            public Object getResultValue(ResultSet rs, FxLanguage language)
338:                    throws FxSqlSearchException {
339:                final FxValue result;
340:                int pos = positionInResultSet;
341:                // Handle by type
342:                try {
343:                    switch (overrideDataType == null ? property.getDataType()
344:                            : overrideDataType) {
345:                    case DateTime:
346:                        if (rs.getMetaData().getColumnType(pos) == java.sql.Types.BIGINT) {
347:                            result = new FxDateTime(multilanguage,
348:                                    FxLanguage.SYSTEM_ID, new Date(rs
349:                                            .getLong(pos)));
350:                            break;
351:                        }
352:                        Timestamp dttstp = rs.getTimestamp(pos);
353:                        Date _dtdate = new Date(dttstp.getTime());
354:                        result = new FxDateTime(multilanguage,
355:                                FxLanguage.SYSTEM_ID, _dtdate);
356:                        break;
357:                    case Date:
358:                        Timestamp tstp = rs.getTimestamp(pos);
359:                        Date _date = new Date(tstp.getTime());
360:                        result = new FxDate(multilanguage,
361:                                FxLanguage.SYSTEM_ID, _date);
362:                        break;
363:                    case DateRange:
364:                        final Date from = new Date(rs.getTimestamp(pos)
365:                                .getTime()); // FDATE1
366:                        final Date to = new Date(rs.getTimestamp(pos + 4)
367:                                .getTime()); // FDATE2
368:                        result = new FxDateRange(new DateRange(from, to));
369:                        break;
370:                    case DateTimeRange:
371:                        final Date from2 = new Date(rs.getTimestamp(pos)
372:                                .getTime()); // FDATE1
373:                        final Date to2 = new Date(rs.getTimestamp(pos + 7)
374:                                .getTime()); // FDATE2
375:                        result = new FxDateTimeRange(new DateRange(from2, to2));
376:                        break;
377:                    case HTML:
378:                        result = new FxHTML(multilanguage,
379:                                FxLanguage.SYSTEM_ID, rs.getString(pos));
380:                        break;
381:                    case String1024:
382:                    case Text:
383:                        result = new FxString(multilanguage,
384:                                FxLanguage.SYSTEM_ID, rs.getString(pos));
385:                        break;
386:                    case LargeNumber:
387:                        result = new FxLargeNumber(multilanguage,
388:                                FxLanguage.SYSTEM_ID, rs.getLong(pos));
389:                        break;
390:                    case Number:
391:                        result = new FxNumber(multilanguage,
392:                                FxLanguage.SYSTEM_ID, rs.getInt(pos));
393:                        break;
394:                    case Float:
395:                        result = new FxFloat(multilanguage,
396:                                FxLanguage.SYSTEM_ID, rs.getFloat(pos));
397:                        break;
398:                    case Boolean:
399:                        result = new FxBoolean(multilanguage,
400:                                FxLanguage.SYSTEM_ID, rs.getBoolean(pos));
401:                        break;
402:                    case Double:
403:                        result = new FxDouble(multilanguage,
404:                                FxLanguage.SYSTEM_ID, rs.getDouble(pos));
405:                        break;
406:                    case Reference:
407:                        result = new FxReference(new ReferencedContent(
408:                                new FxPK(rs.getLong(pos), FxPK.MAX))); // TODO!!
409:                        break;
410:                    case SelectOne:
411:                        FxSelectListItem oneItem = CacheAdmin.getEnvironment()
412:                                .getSelectListItem(rs.getLong(pos));
413:                        result = new FxSelectOne(multilanguage,
414:                                FxLanguage.SYSTEM_ID, oneItem);
415:                        break;
416:                    case SelectMany:
417:                        FxSelectListItem manyItem = CacheAdmin.getEnvironment()
418:                                .getSelectListItem(rs.getLong(pos));
419:                        SelectMany valueMany = new SelectMany(manyItem
420:                                .getList());
421:                        valueMany.selectFromList(rs.getString(pos + 1));
422:                        result = new FxSelectMany(multilanguage,
423:                                FxLanguage.SYSTEM_ID, valueMany);
424:                        break;
425:                    case Binary:
426:                        result = new FxBinary(multilanguage,
427:                                FxLanguage.SYSTEM_ID, new BinaryDescriptor());
428:                        break;
429:                    default:
430:                        throw new FxSqlSearchException(LOG,
431:                                "ex.sqlSearch.reader.UnknownColumnType", String
432:                                        .valueOf(getProperty().getDataType()));
433:                    }
434:
435:                    if (rs.wasNull()) {
436:                        result.setEmpty(language.getId());
437:                    }
438:
439:                    // Get the XPATH if we are reading from the content data table
440:                    if (getTableType() == PropertyResolver.Table.T_CONTENT_DATA) {
441:                        result.setXPath(rs.getString(positionInResultSet
442:                                + getReadColumns().length));
443:                    }
444:
445:                    return result;
446:                } catch (SQLException e) {
447:                    throw new FxSqlSearchException(e);
448:                }
449:            }
450:
451:            /**
452:             * Return the entry type.
453:             *
454:             * @return  the entry type.
455:             */
456:            public Type getType() {
457:                return type;
458:            }
459:
460:            /**
461:             * Overrides the data type this entry represents, e.g. by selectors that load property
462:             * fields from an external table like the {@link com.flexive.core.search.mysql.MySQLACLSelector}.
463:             *
464:             * @param type  the data type of this entry
465:             */
466:            public void overrideDataType(FxDataType type) {
467:                this .overrideDataType = type;
468:            }
469:
470:            /**
471:             * Set the entry's result set index while the query is being built.
472:             *
473:             * @param positionInResultSet   the entry's result set index
474:             */
475:            void setPositionInResultSet(int positionInResultSet) {
476:                this .positionInResultSet = positionInResultSet;
477:            }
478:
479:            /**
480:             * Return the table type if it's a predefined table (like FX_CONTENT), null otherwise.
481:             *
482:             * @return  the table type if it's a predefined table (like FX_CONTENT), null otherwise.
483:             */
484:            public PropertyResolver.Table getTableType() {
485:                return tbl;
486:            }
487:
488:            /**
489:             * The column(s) to read the result from.
490:             *
491:             * @return the column(s) to read the result from
492:             */
493:            public String[] getReadColumns() {
494:                return readColumns;
495:            }
496:
497:            /**
498:             * Return the column name to be used for filtering (i.e. in the 'WHERE' clause of the query).
499:             *
500:             * @return  the column name to be used for filtering
501:             */
502:            public String getFilterColumn() {
503:                return filterColumn;
504:            }
505:
506:            /**
507:             * Return the database table name to be used for selecting/filtering, e.g.
508:             * FX_CONTENT_DATA.
509:             *
510:             * @return  the database table name to be used for selecting/filtering
511:             */
512:            public String getTableName() {
513:                return StringUtils.defaultString(tableName, tbl.getTableName());
514:            }
515:
516:            /**
517:             * Returns the structure property, may be null if this entry does not actually represent
518:             * a structure element.
519:             *
520:             * @return  the structure property
521:             */
522:            public FxProperty getProperty() {
523:                return property;
524:            }
525:
526:            /**
527:             * Returns true if this entry represents a structure (property) assignment.
528:             *
529:             * @return  true if this entry represents a structure (property) assignment.
530:             */
531:            public boolean isAssignment() {
532:                return assignment != null;
533:            }
534:
535:            /**
536:             * Returns the (property) assignment. May be null if this entry does not represent
537:             * a structure element.
538:             *
539:             * @return  the property assignment
540:             */
541:            public FxPropertyAssignment getAssignment() {
542:                return assignment;
543:            }
544:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.