001: /*
002: * Copyright 2007 Outerthought bvba and Schaubroeck nv
003: *
004: * Licensed under the Apache License, Version 2.0 (the "License");
005: * you may not use this file except in compliance with the License.
006: * You may obtain a copy of the License at
007: *
008: * http://www.apache.org/licenses/LICENSE-2.0
009: *
010: * Unless required by applicable law or agreed to in writing, software
011: * distributed under the License is distributed on an "AS IS" BASIS,
012: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013: * See the License for the specific language governing permissions and
014: * limitations under the License.
015: */
016: package org.outerj.daisy.tools.importexport.import_.tm;
017:
018: import org.outerj.daisy.tools.importexport.import_.fs.ImportFile;
019: import org.outerj.daisy.tools.importexport.import_.fs.ImportFileEntry;
020: import org.outerj.daisy.tools.importexport.import_.ImportListener;
021: import org.outerj.daisy.tools.importexport.import_.namespaces.NamespaceImporter;
022: import org.outerj.daisy.tools.importexport.import_.documents.DocumentImportResult;
023: import org.outerj.daisy.tools.importexport.import_.config.ImportOptions;
024: import org.outerj.daisy.tools.importexport.docset.DocumentSet;
025: import org.outerj.daisy.tools.importexport.docset.DocumentSetHelper;
026: import org.outerj.daisy.tools.importexport.model.ImpExpVariantKey;
027: import org.outerj.daisy.tools.importexport.ImportExportException;
028: import org.outerj.daisy.tools.importexport.tm.TMConfig;
029: import org.outerj.daisy.repository.Repository;
030: import org.outerj.daisy.repository.AccessException;
031: import org.outerj.daisy.repository.DocumentLockedException;
032: import org.outerj.daisy.repository.variant.LanguageNotFoundException;
033: import org.outerj.daisy.htmlcleaner.HtmlCleanerTemplate;
034:
035: import java.util.Set;
036: import java.util.List;
037: import java.util.ArrayList;
038: import java.util.regex.Pattern;
039: import java.util.regex.PatternSyntaxException;
040: import java.util.regex.Matcher;
041:
042: public class TMImporter {
043: private ImportFile importFile;
044: private DocumentSet documentSet;
045: private Set importSubSet;
046: private ImportListener listener;
047: private Repository repository;
048: private ImportOptions options;
049: private TMConfig tmConfig;
050: private String targetLanguage;
051: private HtmlCleanerTemplate htmlCleanerTemplate;
052:
053: private static Pattern DOC_NAME_PATTERN = Pattern
054: .compile("^([^~]+)~([^~]+).xml$");
055:
056: public static void run(ImportFile importFile,
057: DocumentSet documentSet, Repository repository,
058: ImportOptions options, ImportListener listener,
059: TMConfig tmConfig, String targetLanguage,
060: HtmlCleanerTemplate htmlCleanerTemplate) throws Exception {
061: if (importFile == null)
062: throw new IllegalArgumentException(
063: "Null argument: importFile");
064: if (repository == null)
065: throw new IllegalArgumentException(
066: "Null argument: repository");
067: if (options == null)
068: throw new IllegalArgumentException("Null argument: options");
069: if (listener == null)
070: throw new IllegalArgumentException(
071: "Null argument: listener");
072: if (targetLanguage == null)
073: throw new IllegalArgumentException(
074: "Null argument: targetLanguage");
075: if (tmConfig == null)
076: throw new IllegalArgumentException(
077: "Null argument: tmConfig");
078:
079: new TMImporter(importFile, documentSet, repository, options,
080: listener, tmConfig, targetLanguage, htmlCleanerTemplate)
081: .run();
082: }
083:
084: private TMImporter(ImportFile importFile, DocumentSet documentSet,
085: Repository repository, ImportOptions options,
086: ImportListener listener, TMConfig tmConfig,
087: String targetLanguage,
088: HtmlCleanerTemplate htmlCleanerTemplate) {
089: this .targetLanguage = targetLanguage;
090: this .importFile = importFile;
091: this .documentSet = documentSet;
092: this .listener = listener;
093: this .repository = repository;
094: this .options = options;
095: this .tmConfig = tmConfig;
096: this .htmlCleanerTemplate = htmlCleanerTemplate;
097: }
098:
099: private void run() throws Exception {
100: // Make sure target language exists
101: try {
102: repository.getVariantManager().getLanguage(targetLanguage,
103: false);
104: } catch (LanguageNotFoundException e) {
105: throw new ImportExportException(
106: "The specified target language does not exist: "
107: + targetLanguage, e);
108: }
109:
110: NamespaceImporter.run(importFile, listener, repository);
111: checkInterrupted();
112:
113: determineDocumentSubSet();
114: checkInterrupted();
115:
116: importDocuments();
117: checkInterrupted();
118: }
119:
120: private void determineDocumentSubSet() throws Exception {
121: // Determine subset of docs to import, if any
122: if (documentSet != null) {
123: try {
124: importSubSet = DocumentSetHelper.toImpExpVariantKeys(
125: documentSet.getDocuments(), repository);
126: documentSet = null;
127: } catch (Exception e) {
128: throw new ImportExportException(
129: "Error getting subset of documents to imports.",
130: e);
131: }
132: }
133: }
134:
135: private void importDocuments() throws Exception {
136: listener.startActivity("Importing documents.");
137:
138: // First search for all documents to import
139: listener.info("Determing list of documents to import.");
140: List<DocumentToImport> documentsToImport = new ArrayList<DocumentToImport>();
141: ImportFileEntry[] docEntries = importFile.getRoot()
142: .getChildren();
143:
144: Pattern excludePattern;
145: try {
146: excludePattern = Pattern.compile(options
147: .getExcludeFilesPattern());
148: } catch (PatternSyntaxException e) {
149: throw new ImportExportException(
150: "Error in exclude file pattern: "
151: + options.getExcludeFilesPattern(), e);
152: }
153:
154: for (ImportFileEntry entry : docEntries) {
155: checkInterrupted();
156: Matcher variantExcludeMatcher = excludePattern
157: .matcher(entry.getName());
158: Matcher matcher = DOC_NAME_PATTERN.matcher(entry.getName());
159: if (entry.isDirectory()) {
160: // a directory: silently skip it
161: } else if (variantExcludeMatcher.matches()) {
162: // matches file exclusion pattern, silently skip it
163: } else if (matcher.matches()) {
164: String documentId = matcher.group(1);
165: String branch = matcher.group(2);
166: ImpExpVariantKey key = new ImpExpVariantKey(documentId,
167: branch, targetLanguage);
168: if (importSubSet == null || importSubSet.contains(key))
169: documentsToImport.add(new DocumentToImport(
170: documentId, branch, targetLanguage, entry));
171: } else {
172: listener
173: .info("Encountered a directory that does not match the naming convention (will skip it): "
174: + entry.getPath());
175: }
176: }
177:
178: // Start the actual import
179: listener.info("There are " + documentsToImport.size()
180: + " document/s to import.");
181: listener.startDocumentProgress(documentsToImport.size());
182: try {
183: for (int i = 0; i < documentsToImport.size(); i++) {
184: checkInterrupted();
185: listener.updateDocumentProgress(i);
186: DocumentToImport doc = documentsToImport.get(i);
187: importDocument(doc);
188: }
189: } finally {
190: listener.endDocumentProgress();
191: }
192: }
193:
194: private void importDocument(DocumentToImport doc) throws Exception {
195: String documentId = doc.getDocumentId();
196: String branch = doc.getBranch();
197: String language = doc.getLanguage();
198: ImpExpVariantKey variantKey = new ImpExpVariantKey(documentId,
199: branch, language);
200:
201: DocumentImportResult result = null;
202: boolean gotError = false;
203: try {
204: result = TMDocumentLoader.run(documentId, branch, language,
205: doc.getEntry(), repository, options, listener,
206: tmConfig, htmlCleanerTemplate);
207: } catch (Throwable throwable) {
208: gotError = true;
209: if (throwable instanceof AccessException) {
210: listener.permissionDenied(variantKey,
211: (AccessException) throwable);
212: } else if (throwable instanceof DocumentLockedException) {
213: listener.lockedDocument(variantKey,
214: (DocumentLockedException) throwable);
215: } else {
216: listener.failed(variantKey, throwable);
217: }
218: }
219:
220: if (!gotError) {
221: listener.success(variantKey, result);
222: }
223: }
224:
225: static class DocumentToImport {
226: String documentId;
227: String branch;
228: String language;
229: ImportFileEntry entry;
230:
231: public DocumentToImport(String documentId, String branch,
232: String language, ImportFileEntry entry) {
233: this .documentId = documentId;
234: this .branch = branch;
235: this .language = language;
236: this .entry = entry;
237: }
238:
239: public String getDocumentId() {
240: return documentId;
241: }
242:
243: public String getBranch() {
244: return branch;
245: }
246:
247: public String getLanguage() {
248: return language;
249: }
250:
251: public ImportFileEntry getEntry() {
252: return entry;
253: }
254: }
255:
256: private void checkInterrupted() throws ImportExportException {
257: if (listener.isInterrupted()) {
258: throw new ImportExportException(
259: "Import was interrupted on user's request.");
260: }
261: }
262: }
|