Source Code Cross Referenced for PageRenamer.java in  » Wiki-Engine » JSPWiki » com » ecyrd » jspwiki » 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 » Wiki Engine » JSPWiki » com.ecyrd.jspwiki 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        /*
002:            JSPWiki - a JSP-based WikiWiki clone.
003:
004:            Copyright (C) 2001-2006 Janne Jalkanen (Janne.Jalkanen@iki.fi)
005:
006:            This program is free software; you can redistribute it and/or modify
007:            it under the terms of the GNU Lesser General Public License as published by
008:            the Free Software Foundation; either version 2.1 of the License, or
009:            (at your option) any later version.
010:
011:            This program is distributed in the hope that it will be useful,
012:            but WITHOUT ANY WARRANTY; without even the implied warranty of
013:            MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
014:            GNU Lesser General Public License for more details.
015:
016:            You should have received a copy of the GNU Lesser General Public License
017:            along with this program; if not, write to the Free Software
018:            Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
019:         */
020:        package com.ecyrd.jspwiki;
021:
022:        import java.util.*;
023:
024:        import org.apache.log4j.Logger;
025:        import org.apache.oro.text.regex.*;
026:
027:        import com.ecyrd.jspwiki.attachment.Attachment;
028:        import com.ecyrd.jspwiki.parser.JSPWikiMarkupParser;
029:        import com.ecyrd.jspwiki.parser.MarkupParser;
030:        import com.ecyrd.jspwiki.providers.ProviderException;
031:        import com.ecyrd.jspwiki.providers.WikiAttachmentProvider;
032:        import com.ecyrd.jspwiki.providers.WikiPageProvider;
033:
034:        /**
035:         *  Do all the nitty-gritty work of renaming pages.
036:         *
037:         *  @since 2.4
038:         */
039:        public class PageRenamer {
040:            private static final Logger log = Logger
041:                    .getLogger(PageRenamer.class);
042:
043:            private final WikiEngine m_wikiEngine;
044:
045:            private static final PatternMatcher MATCHER = new Perl5Matcher();
046:
047:            private boolean m_camelCaseLink;
048:            private boolean m_matchEnglishPlurals;
049:
050:            private static final String LONG_LINK_PATTERN = "\\[([\\w\\s]+\\|)?([\\w\\s\\+-/\\?&;@:=%\\#<>$\\.,\\(\\)'\\*]+)?\\]";
051:            private static final String CAMELCASE_LINK_PATTERN = "([[:upper:]]+[[:lower:]]+[[:upper:]]+[[:alnum:]]*)";
052:
053:            private Pattern m_longLinkPattern = null;
054:            private Pattern m_camelCaseLinkPattern = null;
055:
056:            /**
057:             * Constructor, ties this renamer instance to a WikiEngine.
058:             * @param engine the wiki engine
059:             * @param props the properties used to initialize the wiki engine
060:             */
061:            public PageRenamer(WikiEngine engine, Properties props) {
062:                m_wikiEngine = engine;
063:
064:                // Retrieve relevant options
065:                m_matchEnglishPlurals = TextUtil.getBooleanProperty(props,
066:                        WikiEngine.PROP_MATCHPLURALS, false);
067:
068:                m_camelCaseLink = TextUtil.getBooleanProperty(props,
069:                        JSPWikiMarkupParser.PROP_CAMELCASELINKS, false);
070:
071:                // Compile regular expression patterns
072:                PatternCompiler compiler = new Perl5Compiler();
073:
074:                try {
075:                    m_longLinkPattern = compiler.compile(LONG_LINK_PATTERN);
076:                    m_camelCaseLinkPattern = compiler
077:                            .compile(CAMELCASE_LINK_PATTERN);
078:                } catch (MalformedPatternException mpe) {
079:                    log.error("Error compiling regexp patterns.", mpe);
080:                }
081:            }
082:
083:            /**
084:             * Renames, or moves, a wiki page. Can also alter referring wiki
085:             * links to point to the renamed page.
086:             * @param context TODO
087:             * @param oldName           Name of the source page.
088:             * @param newName           Name of the destination page.
089:             * @param changeReferrers   If true, then changes any referring links
090:             *                          to point to the renamed page.
091:             *
092:             * @return The name of the page that the source was renamed to.
093:             *
094:             * @throws WikiException    In the case of an error, such as the destination
095:             *                          page already existing.
096:             */
097:            public String renamePage(WikiContext context, String oldName,
098:                    String newName, boolean changeReferrers)
099:                    throws WikiException {
100:                // Work out the clean version of the new name of the page
101:                newName = MarkupParser.cleanLink(newName.trim());
102:
103:                // Get the collection of pages that the refered to the old name (the From name)...
104:                Collection referrers = getReferrersCollection(oldName);
105:
106:                log.debug("Rename request for page '" + oldName + "' to '"
107:                        + newName + "'");
108:
109:                // Check if we're attempting to rename to a pagename that already exists
110:                if (m_wikiEngine.pageExists(newName)) {
111:                    log.debug("Rename request failed because target page '"
112:                            + newName + "' exists");
113:
114:                    throw new WikiException("Page exists");
115:                }
116:
117:                // Tell the providers to actually move the data around...
118:                movePageData(oldName, newName);
119:                moveAttachmentData(oldName, newName);
120:
121:                m_wikiEngine.getReferenceManager().clearPageEntries(oldName);
122:
123:                // If there were pages refering to the old name, update them to point to the new name...
124:                if (referrers != null) {
125:                    updateReferrersOnRename(context, oldName, newName,
126:                            changeReferrers, referrers);
127:                } else {
128:                    // Now we need to go and update.
129:                    WikiPage p = m_wikiEngine.getPage(newName);
130:                    String pagedata = m_wikiEngine.getPureText(p);
131:                    Collection refs = m_wikiEngine.scanWikiLinks(p, pagedata);
132:                    m_wikiEngine.getReferenceManager().updateReferences(
133:                            newName, refs);
134:                }
135:
136:                return newName;
137:            }
138:
139:            // Go gather and return a collection of page names that refer to the old name...
140:            private Collection getReferrersCollection(String oldName) {
141:                TreeSet list = new TreeSet();
142:
143:                WikiPage p = m_wikiEngine.getPage(oldName);
144:
145:                if (p != null) {
146:                    Collection c = m_wikiEngine.getReferenceManager()
147:                            .findReferrers(oldName);
148:
149:                    if (c != null)
150:                        list.addAll(c);
151:
152:                    try {
153:                        Collection attachments = m_wikiEngine
154:                                .getAttachmentManager().listAttachments(p);
155:
156:                        for (Iterator i = attachments.iterator(); i.hasNext();) {
157:                            Attachment att = (Attachment) i.next();
158:
159:                            c = m_wikiEngine.getReferenceManager()
160:                                    .findReferrers(att.getName());
161:
162:                            if (c != null)
163:                                list.addAll(c);
164:                        }
165:                    } catch (ProviderException e) {
166:                        log.error("Cannot list attachments", e);
167:                    }
168:
169:                }
170:
171:                return list;
172:            }
173:
174:            // Loop the collection, calling update for each, tickle the reference manager when done.
175:            private void updateReferrersOnRename(WikiContext context,
176:                    String oldName, String newName, boolean changeReferrers,
177:                    Collection referrers) {
178:                // Make a new list out of this, otherwise there is a ConcurrentModificationException
179:                // when the referrer is modifed at the end of this loop when it no longer refers to
180:                // the original page.
181:                List referrersList = new ArrayList(referrers);
182:                Iterator referrersIterator = referrersList.iterator();
183:                while (referrersIterator.hasNext()) {
184:                    String referrerName = (String) referrersIterator.next();
185:                    updateReferrerOnRename(context, oldName, newName,
186:                            changeReferrers, referrerName);
187:                }
188:
189:                //  Manage self-references, which the RefMgr is not managing for us
190:
191:                updateReferrerOnRename(context, oldName, newName,
192:                        changeReferrers, newName);
193:
194:                m_wikiEngine.getReferenceManager().clearPageEntries(oldName);
195:
196:                String text = m_wikiEngine.getText(newName);
197:
198:                Collection updatedReferrers = m_wikiEngine.scanWikiLinks(
199:                        m_wikiEngine.getPage(newName), text);
200:                m_wikiEngine.getReferenceManager().updateReferences(newName,
201:                        updatedReferrers);
202:            }
203:
204:            // Update the referer, changing text if indicated.
205:            private void updateReferrerOnRename(WikiContext context,
206:                    String oldName, String newName, boolean changeReferrer,
207:                    String referrerName) {
208:                log.debug("oldName = " + oldName);
209:                log.debug("newName = " + newName);
210:                log.debug("referrerName = " + referrerName);
211:
212:                String text = m_wikiEngine.getPureText(referrerName,
213:                        WikiProvider.LATEST_VERSION);
214:
215:                if (changeReferrer) {
216:                    text = changeReferrerText(oldName, newName, referrerName,
217:                            text);
218:                }
219:
220:                try {
221:
222:                    WikiContext tempCtx = new WikiContext(m_wikiEngine,
223:                            m_wikiEngine.getPage(referrerName));
224:
225:                    if (context.getPage() != null) {
226:                        PageLock lock = m_wikiEngine.getPageManager()
227:                                .getCurrentLock(context.getPage());
228:                        m_wikiEngine.getPageManager().unlockPage(lock);
229:
230:                        tempCtx.getPage().setAuthor(
231:                                context.getCurrentUser().getName());
232:                        m_wikiEngine.saveText(tempCtx, text);
233:
234:                        Collection updatedReferrers = m_wikiEngine
235:                                .scanWikiLinks(m_wikiEngine
236:                                        .getPage(referrerName), text);
237:
238:                        m_wikiEngine.getReferenceManager().updateReferences(
239:                                referrerName, updatedReferrers);
240:                    }
241:                } catch (WikiException e) {
242:                    log.error("Unable to update referer on rename!", e);
243:                }
244:
245:            }
246:
247:            /**
248:             * Change the text of each referer to reflect the renamed page.  There are seven starting cases
249:             * and two differnting ending scenarios depending on if the new name is camel or long.
250:             * <pre>
251:             * "Start"                               "A"                                "B"
252:             * 1) OldCleanLink                   --> NewCleanLink                   --> [New Long Link]
253:             * 2) [OldCleanLink]                 --> [NewCleanLink]                 --> [New Long Link]
254:             * 3) [old long text|OldCleanLink]   --> [old long text|NewCleanLink]   --> [old long text|New Long Link]
255:             * 4) [Old Long Link]                --> [NewCleanLink]                 --> [New Long Link]
256:             * 5) [old long text|Old Long Link]  --> [old long text|NewCleanLink]   --> [old long text|New Long Link]
257:             * 6) OldLongLink                    --> NewCleanLink                   --> NewLongLink
258:             * 7) [OldLongLink]                  --> [NewCleanLink]                 --> [NewLongLink]
259:             * </pre>
260:             * It's important to note that case 6 and 7 can exist, but are not expected since they are
261:             * counter intuitive.
262:             * <br/>
263:             * When doing any of the above renames these should not get touched...
264:             * A) OtherOldCleanLink
265:             * B) ~OldCleanLink     <-Um maybe we _should_ rename this one?
266:             * C) [[OldCleanLink]   <-Maybe rename this too?
267:             */
268:            private String changeReferrerText(String oldName, String newName,
269:                    String referrerName, String referrerText) {
270:                // The text we are replacing old links with
271:                // String replacementLink = null;
272:
273:                // Work out whether the new page name is CamelCase or not
274:                // TODO: Check if the pattern can be replaced with the compiled version
275:                /*
276:                if( m_camelCaseLink == false || !m_perlUtil.match( "/" + m_camelCaseLinkPatternString + "/", newName ) )
277:                {
278:                    replacementLink = "["+newName+"]";
279:                }
280:                else
281:                {
282:                    replacementLink = newName;
283:                }
284:                 */
285:                // replacementLink = "["+newName+"]";
286:                // Replace long format links
287:                referrerText = replaceLongLinks(referrerText, oldName, newName);
288:
289:                // Replace CamelCase links
290:                if (m_camelCaseLink == true) {
291:                    referrerText = replaceCamelCaseLinks(referrerText, oldName,
292:                            newName);
293:                }
294:
295:                return referrerText;
296:            }
297:
298:            /**
299:             *  Replace long format links in a piece of text
300:             */
301:            private String replaceLongLinks(String text, String oldName,
302:                    String replacementLink) {
303:                int lastMatchEnd = 0;
304:
305:                PatternMatcherInput input = new PatternMatcherInput(text);
306:
307:                StringBuffer ret = new StringBuffer();
308:
309:                while (MATCHER.contains(input, m_longLinkPattern)) {
310:                    MatchResult matchResult = MATCHER.getMatch();
311:
312:                    ret.append(input.substring(lastMatchEnd, matchResult
313:                            .beginOffset(0)));
314:
315:                    String linkText = matchResult.group(1);
316:                    String link = matchResult.group(2);
317:
318:                    String anchor = "";
319:                    String subpage = "";
320:
321:                    if (link == null) {
322:                        throw new InternalWikiException(
323:                                "Null link while trying to rename!  Culprit text is "
324:                                        + text);
325:                    }
326:
327:                    int hash;
328:                    if ((hash = link.indexOf('#')) != -1) {
329:                        anchor = link.substring(hash);
330:                        link = link.substring(0, hash);
331:                    }
332:
333:                    int slash;
334:                    if ((slash = link.indexOf('/')) != -1) {
335:                        subpage = link.substring(slash);
336:                        link = link.substring(0, slash);
337:                    }
338:
339:                    String linkDestinationPage = checkPluralPageName(MarkupParser
340:                            .cleanLink(link));
341:
342:                    if (linkDestinationPage.equals(oldName)) {
343:                        String properReplacement;
344:
345:                        if (linkText != null) {
346:                            properReplacement = '[' + linkText
347:                                    + replacementLink + subpage + anchor + ']';
348:                        } else {
349:                            properReplacement = '[' + replacementLink + subpage
350:                                    + anchor + ']';
351:                        }
352:
353:                        ret.append(properReplacement);
354:                    } else {
355:                        ret.append(input.substring(matchResult.beginOffset(0),
356:                                matchResult.endOffset(0)));
357:                    }
358:
359:                    lastMatchEnd = matchResult.endOffset(0);
360:                }
361:
362:                ret.append(input.substring(lastMatchEnd));
363:
364:                return ret.toString();
365:            }
366:
367:            // Replace CamelCase format links in a piece of text
368:            private String replaceCamelCaseLinks(String text, String oldName,
369:                    String replacementLink) {
370:                int lastMatchEnd = 0;
371:
372:                PatternMatcherInput input = new PatternMatcherInput(text);
373:
374:                StringBuffer ret = new StringBuffer();
375:
376:                while (MATCHER.contains(input, m_camelCaseLinkPattern)) {
377:                    MatchResult matchResult = MATCHER.getMatch();
378:
379:                    ret.append(input.substring(lastMatchEnd, matchResult
380:                            .beginOffset(0)));
381:
382:                    // Check if there's the tilde to stop this being a camel case link
383:                    int matchOffset = matchResult.beginOffset(0);
384:
385:                    char charBefore = 0;
386:
387:                    if (matchOffset != 0) {
388:                        charBefore = input.charAt(matchOffset - 1);
389:                    }
390:
391:                    // Check if the CamelCase link has been escaped
392:                    if (charBefore != '~') {
393:                        // Check if this link maps to our page
394:                        String page = checkPluralPageName(matchResult.group(0));
395:
396:                        if (page.equals(oldName)) {
397:                            ret.append(replacementLink);
398:                        } else {
399:                            ret.append(input.substring(matchResult
400:                                    .beginOffset(0), matchResult.endOffset(0)));
401:                        }
402:                    } else {
403:                        ret.append(input.substring(matchResult.beginOffset(0),
404:                                matchResult.endOffset(0)));
405:                    }
406:
407:                    lastMatchEnd = matchResult.endOffset(0);
408:                }
409:
410:                ret.append(input.substring(lastMatchEnd));
411:
412:                return ret.toString();
413:            }
414:
415:            /**
416:             * Checks if a name is plural, and if so, checks if the page with plural
417:             * exists, otherwise it returns the singular version of the name.
418:             * @param pageName the name of the page
419:             * @return the corrected page name
420:             */
421:            public String checkPluralPageName(String pageName) {
422:                if (pageName == null) {
423:                    return null;
424:                }
425:
426:                if (m_matchEnglishPlurals) {
427:                    try {
428:                        if (pageName.endsWith("s")
429:                                && !m_wikiEngine.getPageManager().pageExists(
430:                                        pageName)) {
431:                            pageName = pageName.substring(0,
432:                                    pageName.length() - 1);
433:                        }
434:                    } catch (ProviderException e) {
435:                        log.error("Unable to check Plural Pagename!", e);
436:                    }
437:                }
438:
439:                return pageName;
440:            }
441:
442:            //Move the page data from the old name to the new name.
443:            private void movePageData(String oldName, String newName)
444:                    throws WikiException {
445:                WikiPageProvider pageProvider = m_wikiEngine.getPageManager()
446:                        .getProvider();
447:
448:                try {
449:                    pageProvider.movePage(oldName, newName);
450:                } catch (ProviderException pe) {
451:                    log.debug("Failed in .movePageData()", pe);
452:                    throw new WikiException(pe.getMessage());
453:                }
454:            }
455:
456:            //Move the attachment data from the old name to the new name.
457:            private void moveAttachmentData(String oldName, String newName)
458:                    throws WikiException {
459:                WikiAttachmentProvider attachmentProvider = m_wikiEngine
460:                        .getAttachmentManager().getCurrentProvider();
461:
462:                log.debug("Trying to move all attachments from old page name "
463:                        + oldName + " to new page name " + newName);
464:
465:                try {
466:                    attachmentProvider.moveAttachmentsForPage(oldName, newName);
467:                    //moveAttachmentsForPage(oldName, newName);
468:                } catch (ProviderException pe) {
469:                    log.debug("Failed in .moveAttachmentData()", pe);
470:                    throw new WikiException(pe.getMessage());
471:                }
472:            }
473:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.