Source Code Cross Referenced for SearchAndReplace.java in  » Content-Management-System » hippo-cms » nl » hippo » cms » searchandreplace » 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 » hippo cms » nl.hippo.cms.searchandreplace 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


0001:        /*
0002:         * Copyright 2007 Hippo.
0003:         * 
0004:         * Licensed under the Apache License, Version 2.0 (the "License");
0005:         * you may not use this file except in compliance with the License.
0006:         * You may obtain a copy of the License at
0007:         * 
0008:         *      http://www.apache.org/licenses/LICENSE-2.0
0009:         * 
0010:         * Unless required by applicable law or agreed to in writing, software
0011:         * distributed under the License is distributed on an "AS IS" BASIS,
0012:         * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
0013:         * See the License for the specific language governing permissions and
0014:         * limitations under the License.
0015:         */
0016:        package nl.hippo.cms.searchandreplace;
0017:
0018:        import java.io.BufferedInputStream;
0019:        import java.io.ByteArrayInputStream;
0020:        import java.io.ByteArrayOutputStream;
0021:        import java.io.IOException;
0022:        import java.io.InputStream;
0023:        import java.util.Enumeration;
0024:        import java.util.HashMap;
0025:        import java.util.Iterator;
0026:        import java.util.List;
0027:        import java.util.Locale;
0028:        import java.util.Map;
0029:        import java.util.Vector;
0030:        import nl.hippo.cms.searchandreplace.log.SearchAndReplaceLog;
0031:        import nl.hippo.cms.searchandreplace.util.MethodCleanup;
0032:        import nl.hippo.cms.searchandreplace.util.StreamCleanup;
0033:        import org.apache.commons.httpclient.HttpClient;
0034:        import org.apache.commons.httpclient.HttpState;
0035:        import org.apache.commons.httpclient.HttpStatus;
0036:        import org.apache.commons.httpclient.MultiThreadedHttpConnectionManager;
0037:        import org.apache.commons.httpclient.methods.GetMethod;
0038:        import org.apache.commons.httpclient.methods.PutMethod;
0039:        import org.apache.webdav.lib.Property;
0040:        import org.apache.webdav.lib.PropertyName;
0041:        import org.apache.webdav.lib.methods.PropFindMethod;
0042:        import org.jdom.Attribute;
0043:        import org.jdom.Document;
0044:        import org.jdom.JDOMException;
0045:        import org.jdom.Text;
0046:        import org.jdom.input.SAXBuilder;
0047:        import org.jdom.output.Format;
0048:        import org.jdom.output.XMLOutputter;
0049:        import org.jdom.xpath.XPath;
0050:        import org.w3c.dom.Element;
0051:        import org.w3c.dom.NodeList;
0052:
0053:        /**
0054:         * <p>
0055:         * This class replaces text in text, CDATA and attribute nodes of a set of
0056:         * documents. It only supports plain searches (i.e. no regular expressions,
0057:         * wildcards, etc.), and can search case-sensitivie and insensitive.
0058:         * </p>
0059:         */
0060:        public class SearchAndReplace implements  Runnable {
0061:            /**
0062:             * <p>
0063:             * The key of the HTTP status code in the map containing the document
0064:             * information needed to make the decision of the document can be
0065:             * processed.
0066:             * </p>
0067:             */
0068:            private static final String HTTP_STATUS_CODE_KEY = "httpStatusCode";
0069:
0070:            /**
0071:             * <p>
0072:             * The key of the current user privilege set in the map containing the
0073:             * document information needed to make the decision of the document can
0074:             * be processed.
0075:             * </p>
0076:             */
0077:            private static final String CURRENT_USER_PRIVILEGE_SET_KEY = "currentUserPrivilegeSet";
0078:
0079:            /**
0080:             * <p>
0081:             * The key of the lock discovery in the map containing the document
0082:             * information needed to make the decision of the document can be
0083:             * processed.
0084:             * </p>
0085:             */
0086:            private static final String LOCK_DISCOVERY_KEY = "lockDiscovery";
0087:
0088:            /**
0089:             * <p>
0090:             * The namespace for WebDAV. It is used to for resource properties and
0091:             * tags in requests and responses.
0092:             * </p>
0093:             */
0094:            private static final String DAV_NAMESPACE = "DAV:";
0095:
0096:            /**
0097:             * <p>
0098:             * The (local) name of the property containing the current user
0099:             * privilege set.
0100:             * </p>
0101:             */
0102:            private static final String CURRENT_USER_PRIVILEGE_SET_PROPERTY_LOCAL_NAME = "current-user-privilege-set";
0103:
0104:            /**
0105:             * <p>
0106:             * The property name (the combination of the namespace URI and the local
0107:             * name) of the property containing the current user privilege set.
0108:             * </p>
0109:             */
0110:            private static final PropertyName CURRENT_USER_PRIVILEGE_SET_PROPERTY_NAME = new PropertyName(
0111:                    DAV_NAMESPACE,
0112:                    CURRENT_USER_PRIVILEGE_SET_PROPERTY_LOCAL_NAME);
0113:
0114:            /**
0115:             * <p>
0116:             * The (local) name of the property containing the lock discovery.
0117:             * </p>
0118:             */
0119:            private static final String LOCK_DISCOVERY_PROPERTY_LOCAL_NAME = "lockdiscovery";
0120:
0121:            /**
0122:             * <p>
0123:             * The property name (the combination of the namespace URI and the local
0124:             * name) of the property containing the lock discovery.
0125:             * </p>
0126:             */
0127:            private static final PropertyName LOCK_DISCOVERY_PROPERTY_NAME = new PropertyName(
0128:                    DAV_NAMESPACE, LOCK_DISCOVERY_PROPERTY_LOCAL_NAME);
0129:
0130:            /**
0131:             * <p>
0132:             * The collection of property names of the properties that are needed
0133:             * for making the decision if the document can be processed.
0134:             * </p>
0135:             */
0136:            private static final Vector PROPERTY_NAMES_NEEDED_FOR_PROCESSABLE_DECISION = new Vector();
0137:
0138:            static {
0139:                PROPERTY_NAMES_NEEDED_FOR_PROCESSABLE_DECISION
0140:                        .add(CURRENT_USER_PRIVILEGE_SET_PROPERTY_NAME);
0141:                PROPERTY_NAMES_NEEDED_FOR_PROCESSABLE_DECISION
0142:                        .add(LOCK_DISCOVERY_PROPERTY_NAME);
0143:            }
0144:
0145:            /**
0146:             * <p>
0147:             * The (local) name of the tag representing the <code>DAV:write</code>
0148:             * privilege.
0149:             * </p>
0150:             */
0151:            private static final String WRITE_LOCAL_NAME = "write";
0152:
0153:            /**
0154:             * <p>
0155:             * The (local) name of the tag indicating that a lock is active on the
0156:             * document.
0157:             * </p>
0158:             */
0159:            private static final String ACTIVE_LOCK_LOCAL_NAME = "activelock";
0160:
0161:            /**
0162:             * <p>
0163:             * The value returned by {@link String#indexOf(String, int)} (and
0164:             * similar functions) if the text cannot be found.
0165:             * </p>
0166:             */
0167:            private static final int STRING_NOT_FOUND_INDEX = -1;
0168:
0169:            /**
0170:             * <p>
0171:             * The configuration containing the information and services needed by
0172:             * this class.
0173:             * </p>
0174:             */
0175:            private SearchAndReplaceConfiguration m_configuration;
0176:
0177:            /**
0178:             * <p>
0179:             * The text that should be replaced. If the search is case-insensitive
0180:             * this text is the lower case version of the text in the configuration.
0181:             * </p>
0182:             */
0183:            private String m_textToSearchFor;
0184:
0185:            /**
0186:             * <p>
0187:             * The HTTP client that will be used to communicate with the WebDAV
0188:             * repository.
0189:             * </p>
0190:             */
0191:            private HttpClient m_httpClient;
0192:
0193:            /**
0194:             * <p>
0195:             * Create an instance of this class passing it the information and
0196:             * services it needs.
0197:             * </p>
0198:             * 
0199:             * <p>
0200:             * The replacement will not be started by the constructor. To start
0201:             * replacement invoke {@link #run()}.
0202:             * </p>
0203:             * 
0204:             * @param configuration
0205:             *                the configuration containing the information and
0206:             *                services needed for replacement.
0207:             */
0208:            public SearchAndReplace(SearchAndReplaceConfiguration configuration) {
0209:                super ();
0210:
0211:                assertConfigurationIsValid(configuration);
0212:
0213:                m_configuration = configuration;
0214:
0215:                determineTextToSearchFor();
0216:                createHttpClient();
0217:            }
0218:
0219:            /**
0220:             * <p>
0221:             * Start the replacement. The listener (in the configuration) is
0222:             * notified of the progress of the replacement.
0223:             * </p>
0224:             */
0225:            public void run() {
0226:                try {
0227:                    Iterator documentUrlsIterator = documentUrlsIterator();
0228:                    /*
0229:                     * Continue processing while not all documents have been
0230:                     * processed and nobody requested this thread to stop.
0231:                     */
0232:                    while (documentUrlsIterator.hasNext()
0233:                            && !Thread.currentThread().isInterrupted()) {
0234:                        String documentUrl = (String) documentUrlsIterator
0235:                                .next();
0236:
0237:                        getListener().startProcessingOfDocument(documentUrl);
0238:
0239:                        try {
0240:                            processDocument(documentUrl);
0241:                        } catch (IOException e) {
0242:                            notifyListenerOfProblemAndLogWarning(
0243:                                    documentUrl,
0244:                                    SearchAndReplaceErrorCodes.IO_EXCEPTION_CODE,
0245:                                    e,
0246:                                    "I/O error occurred while replacing in document: ");
0247:                        } catch (JDOMException e) {
0248:                            notifyListenerOfProblemAndLogWarning(
0249:                                    documentUrl,
0250:                                    SearchAndReplaceErrorCodes.JDOM_EXCEPTION_CODE,
0251:                                    e,
0252:                                    "JDOM error occurred while replacing in document: ");
0253:                        } catch (UnableToReadException e) {
0254:                            notifyListenerOfProblemAndLogWarning(
0255:                                    documentUrl,
0256:                                    SearchAndReplaceErrorCodes.UNABLE_TO_READ_CODE,
0257:                                    e, "Could not read the document: ");
0258:                        } catch (UnableToWriteException e) {
0259:                            notifyListenerOfProblemAndLogWarning(
0260:                                    documentUrl,
0261:                                    SearchAndReplaceErrorCodes.UNABLE_TO_WRITE_CODE,
0262:                                    e, "Could not write the document: ");
0263:                        }
0264:                    }
0265:                } finally {
0266:                    /*
0267:                     * Make sure that the event handler is notified no matter what
0268:                     * happens, because this event might be used to stop listening
0269:                     * by the client.
0270:                     */
0271:                    getListener().replacementFinished();
0272:                }
0273:
0274:            }
0275:
0276:            /**
0277:             * <p>
0278:             * Process a document. Determine if replacement can take place for the
0279:             * document. If so, replace text in the document. Otherwise, notify the
0280:             * listener of the problem.
0281:             * </p>
0282:             * 
0283:             * @param documentUrl
0284:             *                the relative URL of the document to process.
0285:             * @throws IOException
0286:             *                 if an I/O error occurs.
0287:             * @throws JDOMException
0288:             *                 if there is a problem parsing or processing the XML.
0289:             * @throws UnableToReadException
0290:             *                 if the document cannot be read from the repository.
0291:             * @throws UnableToWriteException
0292:             *                 if the document cannot be written to the repository.
0293:             */
0294:            private void processDocument(String documentUrl)
0295:                    throws IOException, JDOMException, UnableToReadException,
0296:                    UnableToWriteException {
0297:                Map documentInformation = retrieveDocumentInformationNeededForProcessableDecision(documentUrl);
0298:                if (canDocumentBeProcessed(documentInformation)) {
0299:                    replaceInDocumentAndReportSuccess(documentUrl);
0300:                } else {
0301:                    reportProblem(documentUrl, documentInformation);
0302:                }
0303:            }
0304:
0305:            /**
0306:             * <p>
0307:             * Replace text in a document. The text to replace, case-sensitivity,
0308:             * where to replace (scope) and the replacement text are specified in
0309:             * the configuration. After replacing notify the listener of successful
0310:             * replacement.
0311:             * </p>
0312:             * 
0313:             * @param documentUrl
0314:             *                the relative URL of the document in which to replace.
0315:             * @throws IOException
0316:             *                 if an I/O error occurs.
0317:             * @throws JDOMException
0318:             *                 if there is a problem parsing or processing the XML.
0319:             * @throws UnableToReadException
0320:             *                 if the document cannot be read from the repository.
0321:             * @throws UnableToWriteException
0322:             *                 if the document cannot be written to the repository.
0323:             */
0324:            private void replaceInDocumentAndReportSuccess(String documentUrl)
0325:                    throws IOException, JDOMException, UnableToReadException,
0326:                    UnableToWriteException {
0327:                int numberOfReplacements = replaceInDocument(documentUrl);
0328:                getListener().successfulProcessingOfDocument(documentUrl,
0329:                        numberOfReplacements);
0330:            }
0331:
0332:            /**
0333:             * <p>
0334:             * Determine why replacement cannot take place for a document and notify
0335:             * the listener of the problem.
0336:             * </p>
0337:             * 
0338:             * @param documentUrl
0339:             *                the relative URL of the document which could not be
0340:             *                processed.
0341:             * @param documentInformation
0342:             *                the information from which to determine the reason for
0343:             *                the problem.
0344:             */
0345:            private void reportProblem(String documentUrl,
0346:                    Map documentInformation) {
0347:                int errorCode = determineErrorCode(documentInformation);
0348:                getListener().unsuccessfulProcessingOfDocument(documentUrl,
0349:                        errorCode);
0350:            }
0351:
0352:            /**
0353:             * <p>
0354:             * Replace text in a document. The text to replace, case-sensitivity,
0355:             * where to replace (scope) and the replacement text are specified in
0356:             * the configuration.
0357:             * </p>
0358:             * 
0359:             * @param documentUrl
0360:             *                the relative URL of the document in which to replace.
0361:             * @return the number of replacements made in the document.
0362:             * @throws IOException
0363:             *                 if an I/O error occurs.
0364:             * @throws JDOMException
0365:             *                 if there is a problem parsing or processing the XML.
0366:             * @throws UnableToReadException
0367:             *                 if the document cannot be read from the repository.
0368:             * @throws UnableToWriteException
0369:             *                 if the document cannot be written to the repository.
0370:             */
0371:            private int replaceInDocument(String documentUrl)
0372:                    throws IOException, JDOMException, UnableToReadException,
0373:                    UnableToWriteException {
0374:                int result;
0375:
0376:                Document document = retrieveDocument(documentUrl);
0377:
0378:                result = replaceInDocument(document);
0379:
0380:                if (0 < result) {
0381:                    // STATE: the document has been changed
0382:
0383:                    storeDocument(documentUrl, document);
0384:                }
0385:
0386:                return result;
0387:            }
0388:
0389:            /**
0390:             * <p>
0391:             * Replace text in a document. The text to replace, case-sensitivity,
0392:             * where to replace (scope) and the replacement text are specified in
0393:             * the configuration.
0394:             * </p>
0395:             * 
0396:             * @param document
0397:             *                the document in which to replace.
0398:             * @return the number of replacements made in the document.
0399:             * @throws JDOMException
0400:             *                 if there is a problem processing the XML.
0401:             */
0402:            private int replaceInDocument(Document document)
0403:                    throws JDOMException {
0404:                int result = 0;
0405:
0406:                List nodes = XPath.selectNodes(document, getScopeXpath());
0407:                for (Iterator nodesIterator = nodes.iterator(); nodesIterator
0408:                        .hasNext();) {
0409:                    Object node = nodesIterator.next();
0410:
0411:                    result += replaceInNodeIfAllowed(node);
0412:                }
0413:
0414:                return result;
0415:            }
0416:
0417:            /**
0418:             * <p>
0419:             * Replace text in an XML node. Only text, CDATA and attribute nodes
0420:             * will be processed. It is allowed to pass in other nodes but these
0421:             * remain unchanged. The text to replace, case-sensitivity and the
0422:             * replacement text are specified in the configuration.
0423:             * </p>
0424:             * 
0425:             * @param node
0426:             *                the node in which to replace.
0427:             * @return the number of replacements made in the document.
0428:             */
0429:            private int replaceInNodeIfAllowed(Object node) {
0430:                int result = 0;
0431:
0432:                if (node instanceof  Text) {
0433:                    Text text = (Text) node;
0434:                    result = replaceInText(text);
0435:                } else if (node instanceof  Attribute) {
0436:                    Attribute attribute = (Attribute) node;
0437:                    result = replaceInAttribute(attribute);
0438:                }
0439:
0440:                return result;
0441:            }
0442:
0443:            /**
0444:             * <p>
0445:             * Replace text in a text or CDATA node. The text to replace,
0446:             * case-sensitivity and the replacement text are specified in the
0447:             * configuration.
0448:             * </p>
0449:             * 
0450:             * @param text
0451:             *                the text or CDATA node in which to replace.
0452:             * @return the number of replacements made in the document.
0453:             */
0454:            private int replaceInText(Text text) {
0455:                int result;
0456:
0457:                ReplacementResult replacementResult = replaceInString(text
0458:                        .getText());
0459:                result = replacementResult.getNumberOfReplacements();
0460:                text.setText(replacementResult.getResultString());
0461:
0462:                return result;
0463:            }
0464:
0465:            /**
0466:             * <p>
0467:             * Replace text in an attribute node. The text to replace,
0468:             * case-sensitivity and the replacement text are specified in the
0469:             * configuration.
0470:             * </p>
0471:             * 
0472:             * @param attribute
0473:             *                the attribute node in which to replace.
0474:             * @return the number of replacements made in the document.
0475:             */
0476:            private int replaceInAttribute(Attribute attribute) {
0477:                int result;
0478:
0479:                ReplacementResult replacementResult = replaceInString(attribute
0480:                        .getValue());
0481:                result = replacementResult.getNumberOfReplacements();
0482:                attribute.setValue(replacementResult.getResultString());
0483:                return result;
0484:            }
0485:
0486:            /**
0487:             * <p>
0488:             * Replace text in a string. The actual text to replace in and the
0489:             * actual search text that are used depend on the case-sensitivity
0490:             * setting. The replacement text is specified in the configuration.
0491:             * </p>
0492:             * 
0493:             * @param string
0494:             *                the string in which to replace.
0495:             * @return an object containing the string after replacement and the
0496:             *         number of replacements done.
0497:             */
0498:            private ReplacementResult replaceInString(String string) {
0499:                ReplacementResult result;
0500:
0501:                /*
0502:                 * Depending on the case-sensitivity of the search the string that
0503:                 * should be used to search in can differ from the string passed in.
0504:                 */
0505:                String stringToSearchIn = getStringToSearchIn(string);
0506:
0507:                int textToSearchForLength = m_textToSearchFor.length();
0508:
0509:                StringBuffer resultString = new StringBuffer(string.length());
0510:
0511:                int numberOfReplacements = 0;
0512:
0513:                int indexToStartSearchingFrom = 0;
0514:                int indexOfTextToReplace = stringToSearchIn.indexOf(
0515:                        m_textToSearchFor, indexToStartSearchingFrom);
0516:                while (indexOfTextToReplace != STRING_NOT_FOUND_INDEX) {
0517:                    /*
0518:                     * Append the text that does not contain the text to replace.
0519:                     */
0520:                    resultString.append(string.substring(
0521:                            indexToStartSearchingFrom, indexOfTextToReplace));
0522:                    /*
0523:                     * Append the replacement text at the location of the text to
0524:                     * replace.
0525:                     */
0526:                    resultString.append(getReplacementText());
0527:
0528:                    numberOfReplacements += 1;
0529:
0530:                    indexToStartSearchingFrom = indexOfTextToReplace
0531:                            + textToSearchForLength;
0532:                    indexOfTextToReplace = stringToSearchIn.indexOf(
0533:                            m_textToSearchFor, indexToStartSearchingFrom);
0534:                }
0535:
0536:                /*
0537:                 * Append the remaining text that does not contain the text to replace.
0538:                 */
0539:                resultString
0540:                        .append(string.substring(indexToStartSearchingFrom));
0541:
0542:                result = new ReplacementResult(resultString.toString(),
0543:                        numberOfReplacements);
0544:
0545:                return result;
0546:            }
0547:
0548:            /**
0549:             * <p>
0550:             * Get the string that should be used to search for the text to replace.
0551:             * The result depends on the case-sensitivity setting.
0552:             * </p>
0553:             * 
0554:             * @param string
0555:             *                the original string to replace in.
0556:             * @return the string to search in.
0557:             */
0558:            private String getStringToSearchIn(String string) {
0559:                String result;
0560:
0561:                if (isSearchCaseSensitive()) {
0562:                    result = string;
0563:                } else {
0564:                    result = string.toLowerCase(getLocale());
0565:                }
0566:
0567:                return result;
0568:            }
0569:
0570:            /**
0571:             * <p>
0572:             * Retrieve the document identified by <code>documentUrl</code> as a
0573:             * JDOM tree. The document URL is appeneded to the documents base URL
0574:             * (which is specified in the configuration).
0575:             * </p>
0576:             * 
0577:             * @param documentUrl
0578:             *                the relative URL of the document.
0579:             * @return a JDOM representation of the XML document.
0580:             * @throws IOException
0581:             *                 if an I/O error occurs.
0582:             * @throws JDOMException
0583:             *                 if there is a problem parsing the XML.
0584:             * @throws UnableToReadException
0585:             *                 if the document cannot be read from the repository.
0586:             */
0587:            private Document retrieveDocument(String documentUrl)
0588:                    throws IOException, JDOMException, UnableToReadException {
0589:                Document result;
0590:
0591:                String fullDocumentUrl = getDocumentsBaseUrl() + documentUrl;
0592:                GetMethod get = new GetMethod(fullDocumentUrl);
0593:                try {
0594:                    get.setDoAuthentication(true);
0595:
0596:                    int getResult = m_httpClient.executeMethod(get);
0597:                    if (getResult == HttpStatus.SC_OK) {
0598:                        result = readDocumentFromGet(get);
0599:                    } else {
0600:                        throw new UnableToReadException(
0601:                                "The HTTP status code of the GET was: "
0602:                                        + getResult);
0603:                    }
0604:                } finally {
0605:                    MethodCleanup.releaseConnection(get,
0606:                            "GET for document content", getLog());
0607:                }
0608:
0609:                return result;
0610:            }
0611:
0612:            /**
0613:             * <p>
0614:             * Read a document from the response of a <code>GET</code> method.
0615:             * </p>
0616:             * 
0617:             * @param get
0618:             *                the <code>GET</code> method to read the document
0619:             *                from.
0620:             * @return the read document.
0621:             * @throws IOException
0622:             *                 if an I/O error occurs.
0623:             * @throws JDOMException
0624:             *                 if there is a problem parsing the XML.
0625:             */
0626:            private Document readDocumentFromGet(GetMethod get)
0627:                    throws IOException, JDOMException {
0628:                Document result;
0629:
0630:                InputStream responseInput = get.getResponseBodyAsStream();
0631:                try {
0632:                    BufferedInputStream bufferedResponseInput = new BufferedInputStream(
0633:                            responseInput);
0634:                    try {
0635:                        SAXBuilder saxBuilder = new SAXBuilder(false);
0636:                        result = saxBuilder.build(bufferedResponseInput);
0637:                    } finally {
0638:                        StreamCleanup.close(bufferedResponseInput,
0639:                                "buffered document content", getLog());
0640:                    }
0641:                } finally {
0642:                    StreamCleanup.close(responseInput, "document content",
0643:                            getLog());
0644:                }
0645:
0646:                return result;
0647:            }
0648:
0649:            /**
0650:             * <p>
0651:             * Store the document in the WebDAV repository using the UTF-8 character
0652:             * encoding.
0653:             * </p>
0654:             * 
0655:             * @param documentUrl
0656:             *                the relative document URL.
0657:             * @param document
0658:             *                the document to store.
0659:             * @throws IOException
0660:             *                 if an I/O error occurs.
0661:             * @throws UnableToWriteException
0662:             *                 if the document cannot be written to the repository.
0663:             */
0664:            private void storeDocument(String documentUrl, Document document)
0665:                    throws IOException, UnableToWriteException {
0666:                byte[] documentAsBytes = writeDocumentToByteArray(document);
0667:
0668:                String fullDocumentUrl = getDocumentsBaseUrl() + documentUrl;
0669:                PutMethod put = new PutMethod(fullDocumentUrl);
0670:                try {
0671:                    put.setDoAuthentication(true);
0672:
0673:                    ByteArrayInputStream byteArrayInput = new ByteArrayInputStream(
0674:                            documentAsBytes);
0675:                    try {
0676:                        put.setRequestBody(byteArrayInput);
0677:
0678:                        int putResult = m_httpClient.executeMethod(put);
0679:                        if (putResult != HttpStatus.SC_NO_CONTENT) {
0680:                            throw new UnableToWriteException(
0681:                                    "The HTTP status code of the PUT was: "
0682:                                            + putResult);
0683:                        }
0684:                    } finally {
0685:                        StreamCleanup.close(byteArrayInput,
0686:                                "byte array for result document", getLog());
0687:                    }
0688:                } finally {
0689:                    MethodCleanup.releaseConnection(put,
0690:                            "PUT for document content", getLog());
0691:                }
0692:            }
0693:
0694:            /**
0695:             * <p>
0696:             * Write the XML document to a byte array using the UTF-8 character
0697:             * encoding.
0698:             * </p>
0699:             * 
0700:             * @param document
0701:             *                the document to write to the byte array.
0702:             * @return a byte array containing the UTF-8 representation of the XML
0703:             *         document.
0704:             * @throws IOException
0705:             *                 if an I/O error occurs.
0706:             */
0707:            private byte[] writeDocumentToByteArray(Document document)
0708:                    throws IOException {
0709:                ByteArrayOutputStream byteArrayOutput = new ByteArrayOutputStream();
0710:                try {
0711:                    XMLOutputter outputter = new XMLOutputter();
0712:                    Format format = Format.getCompactFormat();
0713:                    format.setEncoding("UTF-8");
0714:                    outputter.setFormat(format);
0715:                    outputter.output(document, byteArrayOutput);
0716:                } finally {
0717:                    StreamCleanup.close(byteArrayOutput,
0718:                            "byte array for result document", getLog());
0719:                }
0720:
0721:                return byteArrayOutput.toByteArray();
0722:            }
0723:
0724:            /**
0725:             * <p>
0726:             * Retrieve the document information that is needed for making the
0727:             * decision if a document can be processed. This method will retrieve
0728:             * information about the privileges of the current user and the lock (if
0729:             * present).
0730:             * </p>
0731:             * 
0732:             * @param documentUrl
0733:             *                the relative URL of the document.
0734:             * @return a map containing the HTTP status code, privileges and lock
0735:             *         information. (<code>Map&lt;String, Object&gt;</code>)
0736:             * @throws IOException
0737:             *                 if an I/O error occurs.
0738:             */
0739:            private Map retrieveDocumentInformationNeededForProcessableDecision(
0740:                    String documentUrl) throws IOException {
0741:                Map result = new HashMap();
0742:
0743:                Enumeration propertiesToRetrieveEnumeration = PROPERTY_NAMES_NEEDED_FOR_PROCESSABLE_DECISION
0744:                        .elements();
0745:                String fullDocumentUrl = getDocumentsBaseUrl() + documentUrl;
0746:                PropFindMethod propFind = new PropFindMethod(fullDocumentUrl,
0747:                        propertiesToRetrieveEnumeration);
0748:                try {
0749:                    propFind.setDoAuthentication(true);
0750:
0751:                    int propFindResult = m_httpClient.executeMethod(propFind);
0752:                    result.put(HTTP_STATUS_CODE_KEY,
0753:                            new Integer(propFindResult));
0754:
0755:                    addPropertiesToDocumentInformation(result, propFind);
0756:                } finally {
0757:                    MethodCleanup
0758:                            .releaseConnection(
0759:                                    propFind,
0760:                                    "PROPFIND for document properties needed for processable decision",
0761:                                    getLog());
0762:                }
0763:
0764:                return result;
0765:            }
0766:
0767:            /**
0768:             * <p>
0769:             * Add the properties containing information about the privileges of the
0770:             * user and the lock returned by a <code>PROPFIND</code> method to the
0771:             * document information. This method will only add the properties of the
0772:             * first document (if present) returned by the method.
0773:             * </p>
0774:             * 
0775:             * @param documentInformation
0776:             *                the map to which to add the properties.
0777:             * @param propFind
0778:             *                the <code>PROPFIND</code> method that was used to
0779:             *                request the properties.
0780:             */
0781:            private void addPropertiesToDocumentInformation(
0782:                    Map documentInformation, PropFindMethod propFind) {
0783:                Enumeration responseUrlsEnumeration = propFind
0784:                        .getAllResponseURLs();
0785:                if (responseUrlsEnumeration.hasMoreElements()) {
0786:                    String responseUrl = (String) responseUrlsEnumeration
0787:                            .nextElement();
0788:
0789:                    Enumeration propertiesEnumeration = propFind
0790:                            .getResponseProperties(responseUrl);
0791:                    addPropertiesToDocumentInformation(documentInformation,
0792:                            propertiesEnumeration);
0793:                }
0794:            }
0795:
0796:            /**
0797:             * <p>
0798:             * Add the properties containing information about the privileges of the
0799:             * user and the lock to the document information.
0800:             * </p>
0801:             * 
0802:             * @param documentInformation
0803:             *                the map to which to add the properties.
0804:             * @param propertiesEnumeration
0805:             *                the enumeration over the properties.
0806:             */
0807:            private void addPropertiesToDocumentInformation(
0808:                    Map documentInformation, Enumeration propertiesEnumeration) {
0809:                while (propertiesEnumeration.hasMoreElements()) {
0810:                    Property property = (Property) propertiesEnumeration
0811:                            .nextElement();
0812:
0813:                    if (isCurrentUserPrivilegeSetProperty(property)) {
0814:                        Element currentUserPrivilegeSetElement = property
0815:                                .getElement();
0816:                        documentInformation.put(CURRENT_USER_PRIVILEGE_SET_KEY,
0817:                                currentUserPrivilegeSetElement);
0818:                    } else if (isLockDiscoveryProperty(property)) {
0819:                        Element lockDiscoveryElement = property.getElement();
0820:                        documentInformation.put(LOCK_DISCOVERY_KEY,
0821:                                lockDiscoveryElement);
0822:                    }
0823:                }
0824:            }
0825:
0826:            /**
0827:             * <p>
0828:             * Determine if a property contains the current privileges of a user.
0829:             * </p>
0830:             * 
0831:             * @param property
0832:             *                the property of which to determine if it contains
0833:             *                privileges.
0834:             * @return <code>true</code> if the property contains privileges,
0835:             *         <code>false</code> otherwise.
0836:             */
0837:            private boolean isCurrentUserPrivilegeSetProperty(Property property) {
0838:                return doesPropertyHaveName(property,
0839:                        CURRENT_USER_PRIVILEGE_SET_PROPERTY_NAME);
0840:            }
0841:
0842:            /**
0843:             * <p>
0844:             * Determine if a property contains information about a lock.
0845:             * </p>
0846:             * 
0847:             * @param property
0848:             *                the property of which to determine if it contains lock
0849:             *                information.
0850:             * @return <code>true</code> if the property contains lock
0851:             *         information, <code>false</code> otherwise.
0852:             */
0853:            private boolean isLockDiscoveryProperty(Property property) {
0854:                return doesPropertyHaveName(property,
0855:                        LOCK_DISCOVERY_PROPERTY_NAME);
0856:            }
0857:
0858:            /**
0859:             * <p>
0860:             * Determine if a property has a specific name.
0861:             * </p>
0862:             * 
0863:             * @param property
0864:             *                the property of which to determine if it has name
0865:             *                <code>propertyName</code>.
0866:             * @param propertyName
0867:             *                the proerty name.
0868:             * @return <code>true</code> if the property has name
0869:             *         <code>propertyName</code>, <code>false</code> otherwise.
0870:             */
0871:            private boolean doesPropertyHaveName(Property property,
0872:                    PropertyName propertyName) {
0873:                boolean areNamespaceUrisEqual = property.getNamespaceURI()
0874:                        .equals(propertyName.getNamespaceURI());
0875:                boolean areLocalNamesEqual = property.getLocalName().equals(
0876:                        propertyName.getLocalName());
0877:                return areNamespaceUrisEqual && areLocalNamesEqual;
0878:            }
0879:
0880:            /**
0881:             * <p>
0882:             * Determine if replacement can take place for a document. Replacement
0883:             * can take place if the properties of the document were successfully
0884:             * retrieved, the user has the privilege to write the document and the
0885:             * document is not locked.
0886:             * </p>
0887:             * 
0888:             * @param documentInformation
0889:             *                the map containing information about the result of the
0890:             *                <code>PROPFIND</code> method used to retrieve the
0891:             *                properties, and the properties.
0892:             * @return <code>true</code> if replacement can take place for the
0893:             *         document, <code>false</code> otherwise.
0894:             */
0895:            private boolean canDocumentBeProcessed(Map documentInformation) {
0896:                boolean result = false;
0897:
0898:                result = wasPropFindSuccessful(documentInformation)
0899:                        && isWritable(documentInformation)
0900:                        && isUnlocked(documentInformation);
0901:
0902:                return result;
0903:            }
0904:
0905:            /**
0906:             * <p>
0907:             * Determine if a <code>PROPFIND</code> method was executed
0908:             * successfully. The method was successful if a HTTP status code with
0909:             * value <code>SC_MULTI_STATUS</code> (207) is present.
0910:             * </p>
0911:             * 
0912:             * @param documentInformation
0913:             *                the map containing information about the result of the
0914:             *                <code>PROPFIND</code> method used to retrieve the
0915:             *                properties.
0916:             * @return <code>true</code> if the <code>PROPFIND</code> method was
0917:             *         successful, <code>false</code> othwewise.
0918:             */
0919:            private boolean wasPropFindSuccessful(Map documentInformation) {
0920:                boolean result = false;
0921:
0922:                int httpStatusCode = ((Integer) documentInformation
0923:                        .get(HTTP_STATUS_CODE_KEY)).intValue();
0924:                if (httpStatusCode == HttpStatus.SC_MULTI_STATUS) {
0925:                    result = true;
0926:                }
0927:
0928:                return result;
0929:            }
0930:
0931:            /**
0932:             * <p>
0933:             * Determine if a document is writable for the user. The document is
0934:             * writable if the privileges contain <code>DAV:write</code>.
0935:             * </p>
0936:             * 
0937:             * @param documentInformation
0938:             *                the map containing the properties of the document.
0939:             * @return <code>true</code> if the user may write the document,
0940:             *         <code>false</code> otherwise.
0941:             */
0942:            private boolean isWritable(Map documentInformation) {
0943:                boolean result = false;
0944:
0945:                if (documentInformation
0946:                        .containsKey(CURRENT_USER_PRIVILEGE_SET_KEY)) {
0947:                    Element currentUserPrivilegeSetElement = (Element) documentInformation
0948:                            .get(CURRENT_USER_PRIVILEGE_SET_KEY);
0949:                    NodeList davWriteElements = currentUserPrivilegeSetElement
0950:                            .getElementsByTagNameNS(DAV_NAMESPACE,
0951:                                    WRITE_LOCAL_NAME);
0952:                    if (0 < davWriteElements.getLength()) {
0953:                        result = true;
0954:                    }
0955:                }
0956:
0957:                return result;
0958:            }
0959:
0960:            /**
0961:             * <p>
0962:             * Determine if a document is unlocked. The document is unlocked if the
0963:             * information in property <code>DAV:lockdiscovery</code> does not
0964:             * contain <code>DAV:activelock</code>.
0965:             * </p>
0966:             * 
0967:             * @param documentInformation
0968:             *                the map containing the properties of the document.
0969:             * @return <code>true</code> if the document is unlocked,
0970:             *         <code>false</code> otherwise.
0971:             */
0972:            private boolean isUnlocked(Map documentInformation) {
0973:                boolean result = false;
0974:
0975:                if (documentInformation.containsKey(LOCK_DISCOVERY_KEY)) {
0976:                    Element lockDiscoveryElement = (Element) documentInformation
0977:                            .get(LOCK_DISCOVERY_KEY);
0978:                    NodeList davActiveLockElements = lockDiscoveryElement
0979:                            .getElementsByTagNameNS(DAV_NAMESPACE,
0980:                                    ACTIVE_LOCK_LOCAL_NAME);
0981:                    if (davActiveLockElements.getLength() == 0) {
0982:                        result = true;
0983:                    }
0984:                }
0985:
0986:                return result;
0987:            }
0988:
0989:            /**
0990:             * <p>
0991:             * Determine the error code based on the HTTP status code of the
0992:             * <code>PROPFIND</code> method used to retrieve the document
0993:             * properties, the absence of properties or the value of properties.
0994:             * </p>
0995:             * 
0996:             * @param documentInformation
0997:             *                the map containing information about the result of the
0998:             *                <code>PROPFIND</code> method used to retrieve the
0999:             *                properties, and the properties.
1000:             * @return the error code describing the problem or
1001:             *         {@link SearchAndReplaceErrorCodes#UNKNOWN_ERROR_CODE} if the
1002:             *         problem cannot be determined.
1003:             */
1004:            private int determineErrorCode(Map documentInformation) {
1005:                int result = SearchAndReplaceErrorCodes.UNKNOWN_ERROR_CODE;
1006:
1007:                if (!wasPropFindSuccessful(documentInformation)) {
1008:                    result = determineHttpStatusErrorCode(documentInformation);
1009:                } else if (!documentInformation
1010:                        .containsKey(CURRENT_USER_PRIVILEGE_SET_KEY)) {
1011:                    result = SearchAndReplaceErrorCodes.MISSING_CURRENT_USER_PRIVILEGE_SET_CODE;
1012:                } else if (!isWritable(documentInformation)) {
1013:                    result = SearchAndReplaceErrorCodes.UNAUTHORIZED_CODE;
1014:                } else if (!documentInformation.containsKey(LOCK_DISCOVERY_KEY)) {
1015:                    result = SearchAndReplaceErrorCodes.MISSING_LOCK_DISCOVERY_CODE;
1016:                } else if (!isUnlocked(documentInformation)) {
1017:                    result = SearchAndReplaceErrorCodes.LOCKED_CODE;
1018:                } else {
1019:                    result = SearchAndReplaceErrorCodes.UNKNOWN_ERROR_CODE;
1020:                }
1021:
1022:                return result;
1023:            }
1024:
1025:            /**
1026:             * <p>
1027:             * Determine the error code based on the HTTP status code returned by
1028:             * the <code>PROPFIND</code> method.
1029:             * </p>
1030:             * 
1031:             * @param documentInformation
1032:             *                the map containing information about the result of the
1033:             *                <code>PROPFIND</code> method used to retrieve the
1034:             *                document properties.
1035:             * @return the error code describing the problem or
1036:             *         {@link SearchAndReplaceErrorCodes#UNEXPECTED_HTTP_STATUS_CODE}
1037:             *         if the HTTP status code is not a common one.
1038:             */
1039:            private int determineHttpStatusErrorCode(Map documentInformation) {
1040:                int result;
1041:
1042:                int propFindResult = ((Integer) documentInformation
1043:                        .get(HTTP_STATUS_CODE_KEY)).intValue();
1044:                switch (propFindResult) {
1045:                case HttpStatus.SC_NOT_FOUND:
1046:                    result = SearchAndReplaceErrorCodes.DOCUMENT_NOT_FOUND_CODE;
1047:                    break;
1048:                case HttpStatus.SC_FORBIDDEN:
1049:                    result = SearchAndReplaceErrorCodes.FORBIDDEN_CODE;
1050:                    break;
1051:                default:
1052:                    result = SearchAndReplaceErrorCodes.UNEXPECTED_HTTP_STATUS_CODE;
1053:                    break;
1054:                }
1055:
1056:                return result;
1057:            }
1058:
1059:            /**
1060:             * <p>
1061:             * Notify the listener there was a problem (i.e. an exception was
1062:             * thrown) during the processing of a document, and log a warning.
1063:             * </p>
1064:             * 
1065:             * @param documentUrl
1066:             *                the relative URL of the document that was being
1067:             *                processed.
1068:             * @param errorCode
1069:             *                the error code to pass to the listener.
1070:             * @param exception
1071:             *                the exception that occurred.
1072:             * @param message
1073:             *                the message to log. The document URL will be appended
1074:             *                to this message.
1075:             */
1076:            private void notifyListenerOfProblemAndLogWarning(
1077:                    String documentUrl, int errorCode, Exception exception,
1078:                    String message) {
1079:                getListener().unsuccessfulProcessingOfDocument(documentUrl,
1080:                        errorCode);
1081:                getLog().warning(message + documentUrl, exception);
1082:            }
1083:
1084:            /**
1085:             * <p>
1086:             * Determine the text that should be searched for. The text to search
1087:             * for depends on the case-sensitivity setting.
1088:             * </p>
1089:             */
1090:            private void determineTextToSearchFor() {
1091:                if (isSearchCaseSensitive()) {
1092:                    m_textToSearchFor = getTextToReplace();
1093:                } else {
1094:                    m_textToSearchFor = getTextToReplace().toLowerCase(
1095:                            getLocale());
1096:                }
1097:            }
1098:
1099:            /**
1100:             * <p>
1101:             * Create the HTTP client that will be used to communicate with the
1102:             * WebDAV repository.
1103:             * </p>
1104:             */
1105:            private void createHttpClient() {
1106:                m_httpClient = new HttpClient(
1107:                        new MultiThreadedHttpConnectionManager());
1108:                m_httpClient.setState(getHttpState());
1109:            }
1110:
1111:            /**
1112:             * <p>
1113:             * Validate the configuration. If it is not valid throw an
1114:             * {@link IllegalArgumentException}. A configuration is valid if:
1115:             * </p>
1116:             * <table>
1117:             * <tr>
1118:             * <th>Property</th>
1119:             * <th>Requirements</th>
1120:             * </tr>
1121:             * <tr>
1122:             * <td>documentsBaseUrl</td>
1123:             * <td>Cannot be <code>null</code> or an empty string</td>
1124:             * </tr>
1125:             * <tr>
1126:             * <td>scopeXpath</td>
1127:             * <td>Cannot be <code>null</code> or an empty string.</td>
1128:             * </tr>
1129:             * <tr>
1130:             * <td>textToReplace</td>
1131:             * <td>Cannot be <code>null</code> or an empty string.</td>
1132:             * </tr>
1133:             * <tr>
1134:             * <td>locale</td>
1135:             * <td>Cannot be <code>null</code> if the search is case-insensitive.</td>
1136:             * </tr>
1137:             * <tr>
1138:             * <td>replacementText</td>
1139:             * <td>Cannot be <code>null</code>.</td>
1140:             * </tr>
1141:             * <tr>
1142:             * <td>httpState</td>
1143:             * <td>Cannot be <code>null</code>.</td>
1144:             * </tr>
1145:             * <tr>
1146:             * <td>listener</td>
1147:             * <td>Cannot be <code>null</code>.</td>
1148:             * </tr>
1149:             * <tr>
1150:             * <td>log</td>
1151:             * <td>Cannot be <code>null</code>.</td>
1152:             * </tr>
1153:             * </table>
1154:             */
1155:            private static void assertConfigurationIsValid(
1156:                    SearchAndReplaceConfiguration configuration) {
1157:
1158:                String documentsBaseUrl = configuration.getDocumentsBaseUrl();
1159:                if (documentsBaseUrl == null || documentsBaseUrl.equals("")) {
1160:                    throw new IllegalArgumentException(
1161:                            "Documents base URL must not be 'null' or an empty string.");
1162:                }
1163:
1164:                String scopeXpath = configuration.getScopeXpath();
1165:                if (scopeXpath == null || scopeXpath.equals("")) {
1166:                    throw new IllegalArgumentException(
1167:                            "Scope XPath must not be 'null' or an empty string.");
1168:                }
1169:
1170:                String textToReplace = configuration.getTextToReplace();
1171:                if (textToReplace == null || textToReplace.equals("")) {
1172:                    throw new IllegalArgumentException(
1173:                            "Text to replace must not be 'null' or an empty string.");
1174:                }
1175:
1176:                if (!configuration.isSearchCaseSensitive()) {
1177:                    Locale locale = configuration.getLocale();
1178:                    if (locale == null) {
1179:                        throw new IllegalArgumentException(
1180:                                "Locale must not be 'null' if the search is case-insensitive.");
1181:                    }
1182:                }
1183:
1184:                String replacementText = configuration.getReplacementText();
1185:                if (replacementText == null) {
1186:                    throw new IllegalArgumentException(
1187:                            "Replacement text must not be 'null'.");
1188:                }
1189:
1190:                HttpState httpState = configuration.getHttpState();
1191:                if (httpState == null) {
1192:                    throw new IllegalArgumentException(
1193:                            "HTTP state must not be 'null'.");
1194:                }
1195:
1196:                SearchAndReplaceListener listener = configuration.getListener();
1197:                if (listener == null) {
1198:                    throw new IllegalArgumentException(
1199:                            "Listener must not be 'null'.");
1200:                }
1201:
1202:                SearchAndReplaceLog log = configuration.getLog();
1203:                if (log == null) {
1204:                    throw new IllegalArgumentException(
1205:                            "Log must not be 'null'.");
1206:                }
1207:            }
1208:
1209:            /**
1210:             * <p>
1211:             * Get the documents base URL from the configuration.
1212:             * </p>
1213:             * 
1214:             * @return the documents base URL.
1215:             */
1216:            private String getDocumentsBaseUrl() {
1217:                return m_configuration.getDocumentsBaseUrl();
1218:            }
1219:
1220:            /**
1221:             * <p>
1222:             * Get an iterator over the relative document URLs from the
1223:             * configuration.
1224:             * </p>
1225:             * 
1226:             * @return an iterator over the document URLs.
1227:             */
1228:            private Iterator documentUrlsIterator() {
1229:                return m_configuration.documentUrlsIterator();
1230:            }
1231:
1232:            /**
1233:             * <p>
1234:             * Get the XPath of the scope to replace in from the configuration.
1235:             * </p>
1236:             * 
1237:             * @return the XPath of the scope to replace in.
1238:             */
1239:            private String getScopeXpath() {
1240:                return m_configuration.getScopeXpath();
1241:            }
1242:
1243:            /**
1244:             * <p>
1245:             * Get the text to replace from the configuration.
1246:             * </p>
1247:             * 
1248:             * @return the text to replace.
1249:             */
1250:            private String getTextToReplace() {
1251:                return m_configuration.getTextToReplace();
1252:            }
1253:
1254:            /**
1255:             * <p>
1256:             * Get the case-sensitivity of the search from the configuration.
1257:             * </p>
1258:             * 
1259:             * @return the case-sensitivity of the search.
1260:             */
1261:            private boolean isSearchCaseSensitive() {
1262:                return m_configuration.isSearchCaseSensitive();
1263:            }
1264:
1265:            /**
1266:             * <p>
1267:             * Get the locale that should be used to transform strings to lower case
1268:             * if the search is case-insensitive from the configuration.
1269:             * </p>
1270:             * 
1271:             * @return the locale to use to transform strings to lower case.
1272:             */
1273:            private Locale getLocale() {
1274:                return m_configuration.getLocale();
1275:            }
1276:
1277:            /**
1278:             * <p>
1279:             * Get the replacement text from the configuration.
1280:             * </p>
1281:             * 
1282:             * @return the replacement text.
1283:             */
1284:            private String getReplacementText() {
1285:                return m_configuration.getReplacementText();
1286:            }
1287:
1288:            /**
1289:             * <p>
1290:             * Get the HTTP state that must be used by the HTTP client used to
1291:             * communicate with the WebDAV repository from the configuration.
1292:             * </p>
1293:             * 
1294:             * @return the HTTP state.
1295:             */
1296:            private HttpState getHttpState() {
1297:                return m_configuration.getHttpState();
1298:            }
1299:
1300:            /**
1301:             * <p>
1302:             * Get the listener to notify of the progress from the configuration.
1303:             * </p>
1304:             * 
1305:             * @return the listener.
1306:             */
1307:            public SearchAndReplaceListener getListener() {
1308:                return m_configuration.getListener();
1309:            }
1310:
1311:            /**
1312:             * <p>
1313:             * Get the log from the configuration.
1314:             * </p>
1315:             * 
1316:             * @return the log.
1317:             */
1318:            private SearchAndReplaceLog getLog() {
1319:                return m_configuration.getLog();
1320:            }
1321:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.