Source Code Cross Referenced for LocalRepositoryManager.java in  » Content-Management-System » daisy » org » outerj » daisy » repository » serverimpl » 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 » Content Management System » daisy » org.outerj.daisy.repository.serverimpl 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        /*
002:         * Copyright 2004 Outerthought bvba and Schaubroeck nv
003:         *
004:         * Licensed under the Apache License, Version 2.0 (the "License");
005:         * you may not use this file except in compliance with the License.
006:         * You may obtain a copy of the License at
007:         *
008:         *     http://www.apache.org/licenses/LICENSE-2.0
009:         *
010:         * Unless required by applicable law or agreed to in writing, software
011:         * distributed under the License is distributed on an "AS IS" BASIS,
012:         * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013:         * See the License for the specific language governing permissions and
014:         * limitations under the License.
015:         */
016:        package org.outerj.daisy.repository.serverimpl;
017:
018:        import org.outerj.daisy.repository.*;
019:        import org.outerj.daisy.repository.spi.local.PreSaveHook;
020:        import org.outerj.daisy.repository.spi.ExtensionProvider;
021:        import org.outerj.daisy.repository.namespace.NamespaceNotFoundException;
022:        import org.outerj.daisy.repository.user.Role;
023:        import org.outerj.daisy.repository.serverimpl.model.LocalSchemaStrategy;
024:        import org.outerj.daisy.repository.serverimpl.user.LocalUserManagementStrategy;
025:        import org.outerj.daisy.repository.serverimpl.acl.LocalAclStrategy;
026:        import org.outerj.daisy.repository.serverimpl.variant.LocalVariantStrategy;
027:        import org.outerj.daisy.repository.serverimpl.comment.LocalCommentStrategy;
028:        import org.outerj.daisy.repository.commonimpl.*;
029:        import org.outerj.daisy.repository.commonimpl.schema.CommonRepositorySchema;
030:        import org.outerj.daisy.blobstore.BlobStore;
031:        import org.outerj.daisy.cache.DocumentCache;
032:        import org.outerj.daisy.query.QueryFactory;
033:        import org.outerj.daisy.authentication.UserAuthenticator;
034:        import org.outerj.daisy.ftindex.FullTextIndex;
035:        import org.outerj.daisy.summary.DocumentSummarizer;
036:        import org.outerj.daisy.jdbcutil.JdbcHelper;
037:        import org.outerj.daisy.jdbcutil.SqlCounter;
038:        import org.outerj.daisy.linkextraction.LinkExtractor;
039:        import org.outerj.daisy.linkextraction.LinkExtractorManager;
040:        import org.outerj.daisy.plugin.PluginUser;
041:        import org.outerj.daisy.plugin.PluginRegistry;
042:        import org.outerj.daisy.plugin.PluginHandle;
043:        import org.apache.avalon.framework.configuration.Configuration;
044:        import org.apache.avalon.framework.configuration.ConfigurationException;
045:        import org.apache.commons.logging.Log;
046:        import org.apache.commons.logging.LogFactory;
047:
048:        import javax.sql.DataSource;
049:        import javax.annotation.PreDestroy;
050:
051:        import java.sql.*;
052:        import java.util.*;
053:        import java.util.concurrent.ConcurrentHashMap;
054:        import java.util.concurrent.CopyOnWriteArrayList;
055:
056:        public class LocalRepositoryManager implements  RepositoryManager {
057:            private PluginRegistry pluginRegistry;
058:            private CommonRepository commonRepository;
059:            private DataSource dataSource;
060:            private DocumentCache documentCache;
061:            private BlobStore blobStore;
062:            private UserAuthenticator userAuthenticator;
063:            private QueryFactory queryFactory;
064:            private AuthenticatedUser systemUser;
065:            private FullTextIndex fullTextIndex;
066:            private DocumentSummarizer documentSummarizer;
067:            private LinkExtractorManager linkExtractorManager;
068:            private JdbcHelper jdbcHelper;
069:            private String repositoryNamespace;
070:            private Map<String, ExtensionProvider> extensions = new ConcurrentHashMap<String, ExtensionProvider>(
071:                    16, .75f, 1);
072:            private PluginUser<ExtensionProvider> extensionPluginUser = new ExtensionPluginUser();
073:            private List<PluginHandle<PreSaveHook>> preSaveHooks = new CopyOnWriteArrayList<PluginHandle<PreSaveHook>>();
074:            private PluginUser<PreSaveHook> preSaveHookPluginUser = new PreSaveHookPluginUser();
075:            private long expiredLockJanitorInterval;
076:            private Thread expiredLockJanitorThread;
077:            private final Log log = LogFactory.getLog(getClass());
078:            /**
079:             * The database schema version number. Not necessarily the same as the Daisy version number.
080:             * This number only gets augmented on releases where the schema actually changes.
081:             * If changed here, also needs to be changed in daisy-data.xml and the database
082:             * upgrade script.
083:             */
084:            private final static String DB_SCHEMA_VERSION = "2.2";
085:
086:            public LocalRepositoryManager(Configuration configuration,
087:                    DataSource dataSource, BlobStore blobStore,
088:                    DocumentCache documentCache,
089:                    UserAuthenticator userAuthenticator,
090:                    QueryFactory queryFactory, FullTextIndex fullTextIndex,
091:                    DocumentSummarizer documentSummarizer,
092:                    LinkExtractorManager linkExtractorManager,
093:                    PluginRegistry pluginRegistry) throws Exception {
094:                this .dataSource = dataSource;
095:                this .blobStore = blobStore;
096:                this .documentCache = documentCache;
097:                this .userAuthenticator = userAuthenticator;
098:                this .queryFactory = queryFactory;
099:                this .fullTextIndex = fullTextIndex;
100:                this .documentSummarizer = documentSummarizer;
101:                this .linkExtractorManager = linkExtractorManager;
102:                this .pluginRegistry = pluginRegistry;
103:                this .configure(configuration);
104:                this .initialize();
105:                this .start();
106:            }
107:
108:            @PreDestroy
109:            public void destroy() throws Exception {
110:                this .stop();
111:                pluginRegistry.unsetPluginUser(PreSaveHook.class,
112:                        preSaveHookPluginUser);
113:                pluginRegistry.unsetPluginUser(ExtensionProvider.class,
114:                        extensionPluginUser);
115:            }
116:
117:            private void configure(Configuration configuration)
118:                    throws ConfigurationException {
119:                this .expiredLockJanitorInterval = configuration.getChild(
120:                        "expiredLockJanitorInterval").getValueAsLong(60000);
121:                this .repositoryNamespace = configuration.getChild("namespace")
122:                        .getValue();
123:            }
124:
125:            private void initialize() throws Exception {
126:                Context context = new Context();
127:
128:                // The sytem user is a built-in user which has ID 1
129:                this .systemUser = new AuthenticatedUserImpl(1, null,
130:                        new long[] { Role.ADMINISTRATOR },
131:                        new long[] { Role.ADMINISTRATOR }, "$system");
132:
133:                // Get the database-specific JdbcHelper
134:                jdbcHelper = JdbcHelper.getInstance(dataSource, log);
135:
136:                RepositoryStrategy repositoryStrategy = new LocalRepositoryStrategy(
137:                        context, jdbcHelper);
138:                DocumentStrategy documentStrategy = new LocalDocumentStrategy(
139:                        context, systemUser, jdbcHelper);
140:                LocalSchemaStrategy schemaStrategy = new LocalSchemaStrategy(
141:                        context, jdbcHelper);
142:                LocalAclStrategy aclStrategy = new LocalAclStrategy(context,
143:                        systemUser, jdbcHelper);
144:                LocalUserManagementStrategy userManagementStrategy = new LocalUserManagementStrategy(
145:                        context, jdbcHelper, systemUser);
146:                LocalVariantStrategy variantStrategy = new LocalVariantStrategy(
147:                        context, jdbcHelper);
148:                LocalCollectionStrategy collectionStrategy = new LocalCollectionStrategy(
149:                        context, systemUser, jdbcHelper);
150:                LocalCommentStrategy commentStrategy = new LocalCommentStrategy(
151:                        context, systemUser, jdbcHelper);
152:                commonRepository = new LocalCommonRepository(
153:                        repositoryStrategy, documentStrategy, schemaStrategy,
154:                        aclStrategy, userManagementStrategy, variantStrategy,
155:                        collectionStrategy, commentStrategy, context,
156:                        systemUser, documentCache, extensions, jdbcHelper);
157:                commonRepository.addListener(new DocumentCacheInvalidator());
158:
159:                // supply the user
160:                userAuthenticator.setUserManager(new RepositoryImpl(
161:                        commonRepository, systemUser).getUserManager());
162:
163:                checkDatabaseSchema();
164:
165:                assureRepositoryNamespaceRegistered();
166:
167:                pluginRegistry.setPluginUser(PreSaveHook.class,
168:                        preSaveHookPluginUser);
169:                pluginRegistry.setPluginUser(ExtensionProvider.class,
170:                        extensionPluginUser);
171:            }
172:
173:            private void start() throws Exception {
174:                expiredLockJanitorThread = new Thread(new ExpiredLockJanitor(),
175:                        "Daisy Expired Lock Janitor");
176:                expiredLockJanitorThread.start();
177:            }
178:
179:            private void stop() throws Exception {
180:                log.info("Waiting for expired lock janitor thread to end.");
181:                expiredLockJanitorThread.interrupt();
182:                try {
183:                    expiredLockJanitorThread.join();
184:                } catch (InterruptedException e) {
185:                    // ignore
186:                }
187:            }
188:
189:            public Repository getRepository(final Credentials credentials)
190:                    throws RepositoryException {
191:                AuthenticatedUser user = userAuthenticator
192:                        .authenticate(credentials);
193:                return new RepositoryImpl(commonRepository, user);
194:            }
195:
196:            private class ExtensionPluginUser implements 
197:                    PluginUser<ExtensionProvider> {
198:
199:                public void pluginAdded(
200:                        PluginHandle<ExtensionProvider> pluginHandle) {
201:                    extensions.put(pluginHandle.getName(), pluginHandle
202:                            .getPlugin());
203:                }
204:
205:                public void pluginRemoved(
206:                        PluginHandle<ExtensionProvider> pluginHandle) {
207:                    extensions.remove(pluginHandle.getName());
208:                }
209:            }
210:
211:            private class PreSaveHookPluginUser implements 
212:                    PluginUser<PreSaveHook> {
213:
214:                public void pluginAdded(PluginHandle<PreSaveHook> plugin) {
215:                    preSaveHooks.add(plugin);
216:                }
217:
218:                public void pluginRemoved(PluginHandle<PreSaveHook> plugin) {
219:                    preSaveHooks.remove(plugin);
220:                }
221:            }
222:
223:            /**
224:             * Context information for the document implementation
225:             */
226:            public class Context {
227:                private SqlCounter docIdCounter = new SqlCounter(
228:                        "document_sequence", dataSource, log);
229:                private SqlCounter collectionIdCounter = new SqlCounter(
230:                        "collection_sequence", dataSource, log);
231:                private SqlCounter docTypeCounter = new SqlCounter(
232:                        "documenttype_sequence", dataSource, log);
233:                private SqlCounter partTypeCounter = new SqlCounter(
234:                        "parttype_sequence", dataSource, log);
235:                private SqlCounter fieldTypeCounter = new SqlCounter(
236:                        "fieldtype_sequence", dataSource, log);
237:                private SqlCounter localizedStringCounter = new SqlCounter(
238:                        "localizedstring_sequence", dataSource, log);
239:                private SqlCounter commentCounter = new SqlCounter(
240:                        "comment_sequence", dataSource, log);
241:                private SqlCounter eventCounter = new SqlCounter(
242:                        "event_sequence", dataSource, log);
243:                private SqlCounter userCounter = new SqlCounter(
244:                        "user_sequence", dataSource, log);
245:                private SqlCounter roleCounter = new SqlCounter(
246:                        "role_sequence", dataSource, log);
247:                private SqlCounter namespaceCounter = new SqlCounter(
248:                        "namespace_sequence", dataSource, log);
249:
250:                private Context() {
251:                    // private constructor to make sure no-one else can create this
252:                }
253:
254:                public DataSource getDataSource() {
255:                    return dataSource;
256:                }
257:
258:                public QueryFactory getQueryFactory() {
259:                    return queryFactory;
260:                }
261:
262:                public BlobStore getBlobStore() {
263:                    return blobStore;
264:                }
265:
266:                public FullTextIndex getFullTextIndex() {
267:                    return fullTextIndex;
268:                }
269:
270:                public UserAuthenticator getUserAuthenticator() {
271:                    return userAuthenticator;
272:                }
273:
274:                public DocumentSummarizer getDocumentSummarizer() {
275:                    return documentSummarizer;
276:                }
277:
278:                public CommonRepositorySchema getRepositorySchema() {
279:                    return commonRepository.getRepositorySchema();
280:                }
281:
282:                public CommonRepository getCommonRepository() {
283:                    return commonRepository;
284:                }
285:
286:                public Log getLogger() {
287:                    return log;
288:                }
289:
290:                public long getNextDocumentId() throws SQLException {
291:                    return docIdCounter.getNextId();
292:                }
293:
294:                public long getNextCollectionId() throws SQLException {
295:                    return collectionIdCounter.getNextId();
296:                }
297:
298:                public long getNextDocumentTypeId() throws SQLException {
299:                    return docTypeCounter.getNextId();
300:                }
301:
302:                public long getNextPartTypeId() throws SQLException {
303:                    return partTypeCounter.getNextId();
304:                }
305:
306:                public long getNextFieldTypeId() throws SQLException {
307:                    return fieldTypeCounter.getNextId();
308:                }
309:
310:                public long getNextLocalizedStringId() throws SQLException {
311:                    return localizedStringCounter.getNextId();
312:                }
313:
314:                public long getNextCommentId() throws SQLException {
315:                    return commentCounter.getNextId();
316:                }
317:
318:                public long getNextEventId() throws SQLException {
319:                    return eventCounter.getNextId();
320:                }
321:
322:                public long getNextUserId() throws SQLException {
323:                    return userCounter.getNextId();
324:                }
325:
326:                public long getNextRoleId() throws SQLException {
327:                    return roleCounter.getNextId();
328:                }
329:
330:                public long getNextNamespaceId() throws SQLException {
331:                    return namespaceCounter.getNextId();
332:                }
333:
334:                public LinkExtractor getLinkExtractor(String name) {
335:                    return linkExtractorManager.getLinkExtractor(name);
336:                }
337:
338:                public LinkExtractorInfo[] getLinkExtractors() {
339:                    LinkExtractor[] extractors = linkExtractorManager
340:                            .getLinkExtractors();
341:                    LinkExtractorInfo[] extractorInfos = new LinkExtractorInfo[extractors.length];
342:                    for (int i = 0; i < extractorInfos.length; i++) {
343:                        extractorInfos[i] = new LinkExtractorInfoImpl(
344:                                extractors[i].getName(), extractors[i]
345:                                        .getDescription());
346:                    }
347:                    return extractorInfos;
348:                }
349:
350:                public List<PluginHandle<PreSaveHook>> getPreSaveHooks() {
351:                    return preSaveHooks;
352:                }
353:
354:                public String getRepositoryNamespace() {
355:                    return repositoryNamespace;
356:                }
357:            }
358:
359:            /**
360:             * Event listener that removes a document from the cache when it has been updated.
361:             */
362:            private class DocumentCacheInvalidator implements 
363:                    RepositoryListener {
364:                public void repositoryEvent(RepositoryEventType eventType,
365:                        Object id, long updateCount) {
366:                    if (eventType == RepositoryEventType.DOCUMENT_UPDATED
367:                            || eventType == RepositoryEventType.DOCUMENT_DELETED) {
368:                        documentCache.remove((String) id);
369:                        documentCache.removeAvailableVariants((String) id);
370:                    } else if (eventType == RepositoryEventType.COLLECTION_DELETED
371:                            || eventType == RepositoryEventType.COLLECTION_UPDATED) {
372:                        // If a collection is deleted (or its name is changed), we would
373:                        // need to remove/update all cached document objects referencing
374:                        // that collection.
375:                        // To avoid this complexity, we simply clear the entire cache.
376:                        documentCache.clear();
377:                    } else if (eventType == RepositoryEventType.VERSION_UPDATED
378:                            || eventType == RepositoryEventType.DOCUMENT_VARIANT_UPDATED
379:                            || eventType == RepositoryEventType.DOCUMENT_VARIANT_CREATED
380:                            || eventType == RepositoryEventType.DOCUMENT_VARIANT_DELETED) {
381:                        VariantKey variantKey = (VariantKey) id;
382:                        // If a variant is deleted we would need to remove/update all cached
383:                        // objects referencing this variant through document.referenceLanguageId,
384:                        // variant.(live|last)SyncedWith or version.syncedWith.
385:                        // To avoid this complexity, we simply remove the whole document.
386:                        documentCache.remove(variantKey.getDocumentId());
387:                        // removing available variants is needed in all of these event types because
388:                        // availableVariants contains the liveVersionId and the retired flag.
389:                        documentCache.removeAvailableVariants(variantKey
390:                                .getDocumentId());
391:                    } else if (eventType == RepositoryEventType.LOCK_CHANGE) {
392:                        VariantKey variantKey = (VariantKey) id;
393:                        DocumentImpl document = documentCache.get(variantKey
394:                                .getDocumentId(), variantKey.getBranchId(),
395:                                variantKey.getLanguageId());
396:                        if (document != null) {
397:                            document.clearLockInfo();
398:                        }
399:                    }
400:                }
401:            }
402:
403:            private class ExpiredLockJanitor implements  Runnable {
404:                public void run() {
405:                    try {
406:                        while (true) {
407:                            Thread.sleep(expiredLockJanitorInterval);
408:                            Connection conn = null;
409:                            PreparedStatement stmt = null;
410:                            try {
411:                                conn = dataSource.getConnection();
412:                                stmt = conn
413:                                        .prepareStatement("select doc_id, ns_id, ns.name_ as ns_name, branch_id, lang_id from locks left join daisy_namespaces ns on (locks.ns_id = ns.id) where time_expires is not null and time_expires < ?");
414:                                stmt.setTimestamp(1, new Timestamp(System
415:                                        .currentTimeMillis()));
416:                                ResultSet rs = stmt.executeQuery();
417:                                while (rs.next()) {
418:                                    if (Thread.interrupted()) {
419:                                        return;
420:                                    }
421:                                    String documentId = rs.getLong("doc_id")
422:                                            + "-" + rs.getString("ns_name");
423:                                    long branchId = rs.getLong("branch_id");
424:                                    long languageId = rs.getLong("lang_id");
425:                                    try {
426:                                        commonRepository.getDocument(
427:                                                documentId, branchId,
428:                                                languageId, false, systemUser)
429:                                                .getLockInfo(true);
430:                                    } catch (DocumentVariantNotFoundException e) {
431:                                        // ignore
432:                                    } catch (DocumentNotFoundException e) {
433:                                        // ignore
434:                                    } catch (RepositoryException e) {
435:                                        log
436:                                                .error("Error trying to update expired lock info for document "
437:                                                        + documentId
438:                                                        + ", branch "
439:                                                        + branchId
440:                                                        + ", language "
441:                                                        + languageId);
442:                                    }
443:                                }
444:                            } catch (Throwable e) {
445:                                log
446:                                        .error(
447:                                                "Exception occured in ExpiredLockJanitor.",
448:                                                e);
449:                            } finally {
450:                                jdbcHelper.closeStatement(stmt);
451:                                jdbcHelper.closeConnection(conn);
452:                            }
453:                        }
454:                    } catch (InterruptedException e) {
455:                        // ignore
456:                    } finally {
457:                        log.info("Expired lock janitor thread ended.");
458:                    }
459:                }
460:            }
461:
462:            private void checkDatabaseSchema() throws RepositoryException {
463:                Connection conn = null;
464:                PreparedStatement stmt = null;
465:                try {
466:                    conn = dataSource.getConnection();
467:                    stmt = conn
468:                            .prepareStatement("select propvalue from daisy_system where propname = 'schema_version'");
469:                    ResultSet rs = stmt.executeQuery();
470:                    if (!rs.next())
471:                        throw new RepositoryException(
472:                                "No schema_version found in daisy_system table.");
473:                    String version = rs.getString(1);
474:                    if (!DB_SCHEMA_VERSION.equals(version))
475:                        throw new RepositoryException(
476:                                "The repository database schema is not at the correct version: found :\""
477:                                        + version + "\", expected: \""
478:                                        + DB_SCHEMA_VERSION + "\".");
479:                } catch (SQLException e) {
480:                    throw new RepositoryException(
481:                            "Error getting schema version information.", e);
482:                } catch (RepositoryException e) {
483:                    throw e;
484:                } finally {
485:                    jdbcHelper.closeStatement(stmt);
486:                    jdbcHelper.closeConnection(conn);
487:                }
488:            }
489:
490:            public String getRepositoryServerVersion() {
491:                return commonRepository.getServerVersion(systemUser);
492:            }
493:
494:            private void assureRepositoryNamespaceRegistered()
495:                    throws RepositoryException {
496:                try {
497:                    commonRepository.getNamespaceManager().getNamespace(
498:                            repositoryNamespace);
499:                } catch (NamespaceNotFoundException e) {
500:                    log
501:                            .info("The repository's namespace was not yet registered, doing that now.");
502:                    commonRepository.getNamespaceManager().registerNamespace(
503:                            repositoryNamespace, systemUser);
504:                }
505:            }
506:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.