Source Code Cross Referenced for RepositoryUpdateHelper.java in  » Report » pentaho-report » com » pentaho » repository » dbbased » solution » 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 » Report » pentaho report » com.pentaho.repository.dbbased.solution 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        package com.pentaho.repository.dbbased.solution;
002:
003:        import java.io.File;
004:        import java.io.IOException;
005:        import java.util.ArrayList;
006:        import java.util.HashMap;
007:        import java.util.Iterator;
008:        import java.util.List;
009:        import java.util.Map;
010:        import java.util.regex.Pattern;
011:        import org.apache.commons.logging.Log;
012:        import org.apache.commons.logging.LogFactory;
013:        import org.hibernate.Criteria;
014:        import org.hibernate.FetchMode;
015:        import org.hibernate.criterion.Restrictions;
016:        import org.pentaho.core.solution.ISolutionFile;
017:        import org.pentaho.messages.Messages;
018:        import org.pentaho.repository.HibernateUtil;
019:        import org.pentaho.util.FileHelper;
020:
021:        /**
022:         * This class is used for handling all the bits and twiddles of updating the RDBMS Solution Repository. All state during update is handled here.
023:         * 
024:         * @author mbatchel
025:         */
026:        public class RepositoryUpdateHelper {
027:
028:            protected static final Log logger = LogFactory
029:                    .getLog(RepositoryUpdateHelper.class);
030:
031:            String fromBase; // The directory name of the solution
032:
033:            String toBase; // The name of the root folder in the RDBMS
034:
035:            // Holds from->to name replacements
036:            //
037:            // E.g. From: c:\workspace\pentaho\solutions\samples\myfile.xaction
038:            // To: /solutions/samples/myfile.xaction
039:            Map nameReplacementMap = new HashMap();
040:
041:            Map reposFileStructure; // Passed in contains the RDBMS files and folders with last modified dates
042:
043:            Map createdOrRetrievedFolders = new HashMap(); // As the name states
044:
045:            List updatedFiles = new ArrayList();
046:
047:            List newFolders = new ArrayList();
048:
049:            List newFiles = new ArrayList();
050:
051:            List updatedFolders = new ArrayList();
052:
053:            SolutionRepository dbBasedRepository;
054:
055:            private static final Pattern SlashPattern = Pattern.compile("\\\\"); //$NON-NLS-1$
056:
057:            protected RepositoryUpdateHelper(String fromBase, String toBase,
058:                    Map reposFileStructure, SolutionRepository inRepository) {
059:                this .fromBase = fromBase;
060:                this .toBase = toBase;
061:                this .reposFileStructure = reposFileStructure;
062:                dbBasedRepository = inRepository;
063:            }
064:
065:            /**
066:             * Converts the name from a DOS/Windows/Unix canonical name into the name in the RDBMS repository For example: From: c:\workspace\pentaho\solutions\samples\myfile.xaction To: /solutions/samples/myfile.xaction
067:             * 
068:             * @param fName
069:             *          Canonical file name
070:             * @return Fixed file name within the RDBMS repository
071:             */
072:            protected String convertFileName(String fName) {
073:                String rtn = (String) nameReplacementMap.get(fName); // Check to see if I've already done this
074:                if (rtn == null) {
075:                    // Need to do the conversion
076:                    rtn = toBase
077:                            + SlashPattern.matcher(
078:                                    fName.substring(fromBase.length()))
079:                                    .replaceAll("/"); //$NON-NLS-1$
080:                    nameReplacementMap.put(fName, rtn);
081:                }
082:                return rtn;
083:            }
084:
085:            /**
086:             * Process additions (files and folders) by adding them to the repository tree
087:             * 
088:             * @throws IOException
089:             */
090:            protected void processAdditions() throws IOException {
091:                //
092:                // Process New Folders
093:                //
094:                for (int i = 0; i < newFolders.size(); i++) {
095:                    File newFolder = (File) newFolders.get(i);
096:                    RepositoryFile newFolderObject = createFolder(newFolder);
097:                    logger
098:                            .info(Messages
099:                                    .getString(
100:                                            "SolutionRepository.INFO_0004_ADDED_FOLDER", newFolderObject.getFullPath())); //$NON-NLS-1$
101:                }
102:                //
103:                // Process New Files
104:                //
105:                for (int i = 0; i < newFiles.size(); i++) {
106:                    File newFile = (File) newFiles.get(i);
107:                    RepositoryFile newFileObject = createNewFile(newFile);
108:                    logger
109:                            .info(Messages
110:                                    .getString(
111:                                            "SolutionRepository.INFO_0006_ADDED_FILE", newFileObject.getFullPath())); //$NON-NLS-1$
112:                }
113:            }
114:
115:            /**
116:             * Process updates (files and folders) by updating their time and/or updating contents
117:             * 
118:             * @throws IOException
119:             */
120:            protected void processUpdates() throws IOException {
121:                //
122:                // Process Updated Files
123:                //
124:                for (int i = 0; i < updatedFiles.size(); i++) {
125:                    File updatedFile = (File) updatedFiles.get(i);
126:                    String updRepoFileName = convertFileName(updatedFile
127:                            .getCanonicalPath());
128:                    RepositoryFile updRepoFileObject = (RepositoryFile) dbBasedRepository
129:                            .getFileByPath(updRepoFileName); // Hibernate Query
130:                    byte[] data = FileHelper.getBytesFromFile(updatedFile);
131:                    updRepoFileObject.setLastModified(updatedFile
132:                            .lastModified());
133:                    updRepoFileObject.setData(data);
134:                    logger
135:                            .info(Messages
136:                                    .getString(
137:                                            "SolutionRepository.INFO_0007_UPDATED_FILE", updRepoFileObject.getFullPath())); //$NON-NLS-1$
138:                }
139:                //
140:                // Process Updated Folders
141:                //
142:                RepositoryFile updFolderObject = null;
143:                for (int i = 0; i < updatedFolders.size(); i++) {
144:                    File updatedFolder = (File) updatedFolders.get(i);
145:                    String folderNameCorrected = this 
146:                            .convertFileName(updatedFolder.getCanonicalPath());
147:                    // Check for it to already be there...
148:                    updFolderObject = (RepositoryFile) createdOrRetrievedFolders
149:                            .get(folderNameCorrected);
150:                    if (updFolderObject == null) {
151:                        updFolderObject = (RepositoryFile) dbBasedRepository
152:                                .getFileByPath(folderNameCorrected); // Hibernate Query
153:                        createdOrRetrievedFolders.put(folderNameCorrected,
154:                                updFolderObject); // Put it here so we can use it later if needed
155:                    }
156:                    updFolderObject.setLastModified(updatedFolder
157:                            .lastModified()); // Update the date/time stamp
158:                    logger
159:                            .info(Messages
160:                                    .getString(
161:                                            "SolutionRepository.INFO_0002_UPDATED_FOLDER", folderNameCorrected)); //$NON-NLS-1$
162:                }
163:            }
164:
165:            /**
166:             * Processes deletions by looking at the InfoHolder object for items that weren't touched during traversal of the file system.
167:             * 
168:             * @param deleteOrphans
169:             *          Whether to actually delete the items from Hibernate
170:             * @return
171:             */
172:            protected List processDeletions(boolean deleteOrphans) {
173:                // Return (and optionally process) deletions
174:                List deletions = new ArrayList();
175:                Iterator it = reposFileStructure.entrySet().iterator();
176:                while (it.hasNext()) {
177:                    Map.Entry me = (Map.Entry) it.next();
178:                    InfoHolder info = (InfoHolder) me.getValue();
179:                    if (!info.touched) {
180:                        deletions.add(me.getKey());
181:                    }
182:                }
183:                if (deleteOrphans) {
184:                    performHibernateDelete(deletions);
185:                }
186:                return deletions;
187:            }
188:
189:            /**
190:             * Actually deletes the RepositoryFile objects from Hibernate
191:             * 
192:             * @param deletions
193:             *          List of files deleted
194:             */
195:            protected void performHibernateDelete(List deletions) {
196:
197:                // TODO: This should really be handled with a subQuery rather than 
198:                // an in clause... Oracle in clauses are notoriously bad performers.
199:                // Not changing the implementation now as we are releasing 1.6GA soon. 
200:
201:                List listOfDeletions = new ArrayList();
202:                Criteria criteria = null;
203:
204:                if (deletions != null && deletions.size() > 0) {
205:
206:                    if (HibernateUtil.isOracleDialect()) {
207:                        for (int i = 0; i < deletions.size(); i += 500) {
208:                            // Oracle sets a limit on the number of items contained in  
209:                            // the "in" clause on a SQL statement (< 1000). So we are chunking
210:                            // deletions by 500, in case we run into the case where we exceed the Oracle
211:                            // limit. 
212:                            // See the following threads for details:
213:                            // http://www.dbforums.com/showthread.php?t=369013
214:                            // http://jira.pentaho.org:8080/browse/BISERVER-372
215:                            int maxChunkIndex = (i + 500) > deletions.size() ? deletions
216:                                    .size()
217:                                    : (i + 500);
218:                            List chunkDeletions = deletions.subList(i,
219:                                    maxChunkIndex);
220:                            criteria = HibernateUtil.getSession()
221:                                    .createCriteria(RepositoryFile.class);
222:                            criteria.add(Restrictions.in(
223:                                    "fullPath", chunkDeletions)); // Get all objects to be deleted. //$NON-NLS-1$
224:                            listOfDeletions.add(criteria);
225:                        }
226:                    } else { // all other dialects
227:                        criteria = HibernateUtil.getSession().createCriteria(
228:                                RepositoryFile.class);
229:                        criteria.add(Restrictions.in("fullPath", deletions)); // Get all objects to be deleted. //$NON-NLS-1$
230:                        // Due to a bug in the Oracle JDBC driver, we must disable outer join fetching in 
231:                        // Hibernate in order for deletions to execute successfully.
232:                        // See the following threads for details:
233:                        // http://forum.hibernate.org/viewtopic.php?t=82
234:                        // http://forum.hibernate.org/viewtopic.php?t=930650
235:                        // http://jira.pentaho.org/browse/BISERVER-232
236:                        criteria.setFetchMode("parent", FetchMode.JOIN); //$NON-NLS-1$
237:                        listOfDeletions.add(criteria);
238:                    }
239:
240:                    for (Iterator iter = listOfDeletions.iterator(); iter
241:                            .hasNext();) {
242:                        Criteria element = (Criteria) iter.next();
243:                        List deleteResult = element.list(); // Should return all things to be deleted.
244:                        for (int i = 0; i < deleteResult.size(); i++) {
245:                            RepositoryFile toBeDeleted = (RepositoryFile) deleteResult
246:                                    .get(i);
247:                            RepositoryFile deletedParent = (RepositoryFile) toBeDeleted
248:                                    .retrieveParent();
249:                            if (deletedParent != null) {
250:                                deletedParent.removeChildFile(toBeDeleted);
251:                            }
252:                            HibernateUtil.makeTransient(toBeDeleted);
253:                        }
254:                    }
255:                }
256:            }
257:
258:            /**
259:             * Determines whether the folder already exists, or needs to be added.
260:             * 
261:             * @param aFile
262:             *          The File object pointing to the folder on the drive
263:             * @throws IOException
264:             */
265:            protected void recordFolder(File aFile) throws IOException {
266:                String fixedFileName = convertFileName(aFile.getCanonicalPath());
267:                InfoHolder infoHolder = (InfoHolder) reposFileStructure
268:                        .get(fixedFileName);
269:                if (infoHolder != null) {
270:                    infoHolder.touched = true;
271:                    if (aFile.lastModified() != infoHolder.lastModifiedDate) {
272:                        updatedFolders.add(aFile);
273:                    }
274:                } else {
275:                    newFolders.add(aFile);
276:                }
277:            }
278:
279:            /**
280:             * Determines whether a file has been updated or was added.
281:             * 
282:             * @param f
283:             *          File object pointing to the file on the hard drive
284:             * @return true if the file has been changed.
285:             * @throws IOException
286:             */
287:            protected boolean recordFile(File f) throws IOException {
288:                boolean changed = false;
289:                // First, convert the file - this code will move soon
290:                String fName = f.getCanonicalPath();
291:                String convertedSolnFileName = convertFileName(fName);
292:                long lastRDBMSModDate = getLastModifiedDateFromMap(convertedSolnFileName);
293:                if (lastRDBMSModDate > 0) {
294:                    // File is in RDBMS. Check the mode date
295:                    if (f.lastModified() != lastRDBMSModDate) {
296:                        updatedFiles.add(f);
297:                        changed = true;
298:                    }
299:                } else {
300:                    // This file is brand-spankin' new
301:                    newFiles.add(f);
302:                }
303:                return changed;
304:            }
305:
306:            /**
307:             * Retrieves the last modified date from the map returned from Hibernate. Also touches the object in the map to indicate it was traversed during the filesystem crawl
308:             * 
309:             * @param fileName
310:             *          The name of the file to lookup in the map
311:             * @return null if the file isn't already in the RDBMS, or the last modified date/time of the file
312:             */
313:            protected long getLastModifiedDateFromMap(String fileName) {
314:                InfoHolder info = (InfoHolder) reposFileStructure.get(fileName);
315:                if (info != null) {
316:                    info.touched = true;
317:                    return info.lastModifiedDate;
318:                }
319:                return -1;
320:            }
321:
322:            /**
323:             * Gets the parent folder for the file/folder. May result in a Hibernate query if the folder wasn't one that was created during the process. There shouldn't be a way for the folder to not exist. Either it was previously created during this update cycle (in which case it'll already be in the createdOrRetrievedFolders map) or it already existed in the RDBMS Repo in which case it will be retrieved and put in the map.
324:             * 
325:             * @param parentName
326:             *          The solution path to the parent.
327:             * @return RepositoryFile The parent object
328:             */
329:            protected ISolutionFile getParent(String parentName) {
330:                // Check the map first
331:                ISolutionFile theParent = (RepositoryFile) createdOrRetrievedFolders
332:                        .get(parentName);
333:                if (theParent == null) {
334:                    // It's not there - need to get it from the RDBMS
335:                    theParent = dbBasedRepository.getFileByPath(parentName); // Hibernate Query
336:                    createdOrRetrievedFolders.put(parentName, theParent);
337:                }
338:                return theParent;
339:            }
340:
341:            /**
342:             * This method creates a new folder in the RDBMS Repository. This means finding the correct parent (a Hibernate Query may have to be executed to get the parent).
343:             * 
344:             * @param newFolder
345:             *          The File that points to the new folder to create
346:             * @return The RepositoryFile object created
347:             * @throws IOException
348:             */
349:            protected RepositoryFile createFolder(File newFolder)
350:                    throws IOException {
351:                // Determine the corrected file name of the new folder
352:                String fixedFolderName = convertFileName(newFolder
353:                        .getCanonicalPath());
354:                // Get the file's parent folder
355:                File parentFolder = newFolder.getParentFile();
356:                // Get the corrected file name of the parent folder
357:                String fixedParentFolderName = convertFileName(parentFolder
358:                        .getCanonicalPath());
359:                // Get the Parent Folder either from our map or from Hibernate if necessary
360:                RepositoryFile parentFolderObject = (RepositoryFile) getParent(fixedParentFolderName);
361:                // Now, we have the parent in hand, we can create the RepositoryFile object
362:                RepositoryFile newFolderObject = new RepositoryFile(newFolder
363:                        .getName(), parentFolderObject, null, newFolder
364:                        .lastModified());
365:                createdOrRetrievedFolders.put(fixedFolderName, newFolderObject); // Add to map for later potential use
366:                return newFolderObject;
367:            }
368:
369:            /**
370:             * Creates a new RepositoryFile object from the File on the hard drive
371:             * 
372:             * @param newFile
373:             *          The File object pointing to the file on the hard drive
374:             * @return RepositoryFile object created
375:             * @throws IOException
376:             */
377:            protected RepositoryFile createNewFile(File newFile)
378:                    throws IOException {
379:                File parentFolder = newFile.getParentFile(); // Gets the parent folder of the File object
380:                String fixedParentFolderName = convertFileName(parentFolder
381:                        .getCanonicalPath()); // Get the parent RepositoryFile object
382:                RepositoryFile parentFolderObject = (RepositoryFile) getParent(fixedParentFolderName); // Fix up the name for the solution repository
383:                // Create the new Object
384:                RepositoryFile newFileObject = new RepositoryFile(newFile
385:                        .getName(), parentFolderObject, FileHelper
386:                        .getBytesFromFile(newFile), newFile.lastModified());
387:                return newFileObject;
388:            }
389:            /*
390:             * private void deleteFilesFromSolutionTree(List deleteList) { if (deleteList != null) { Iterator iter = deleteList.iterator(); while (iter.hasNext()) { RepositoryFile file = (RepositoryFile) iter.next(); RepositoryFile parent = file.getParent(); if (parent != null) { // this take care of the case of deleting the // repository completely parent.removeChildFile(file); } } } }
391:             */
392:        }
393:
394:        /** *************************** END New Update DB Repository Methods ******************************* */
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.