001: /*
002: * Copyright 2004 Outerthought bvba and Schaubroeck nv
003: *
004: * Licensed under the Apache License, Version 2.0 (the "License");
005: * you may not use this file except in compliance with the License.
006: * You may obtain a copy of the License at
007: *
008: * http://www.apache.org/licenses/LICENSE-2.0
009: *
010: * Unless required by applicable law or agreed to in writing, software
011: * distributed under the License is distributed on an "AS IS" BASIS,
012: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013: * See the License for the specific language governing permissions and
014: * limitations under the License.
015: */
016: package org.outerj.daisy.frontend.editor;
017:
018: import org.outerj.daisy.repository.VariantKey;
019: import org.outerj.daisy.repository.RepositoryException;
020: import org.outerj.daisy.repository.Repository;
021: import org.outerj.daisy.repository.namespace.NamespaceNotFoundException;
022: import org.outerj.daisy.repository.variant.VariantManager;
023: import org.outerj.daisy.repository.variant.BranchNotFoundException;
024: import org.outerj.daisy.repository.variant.LanguageNotFoundException;
025: import org.outerj.daisy.util.Constants;
026: import org.apache.cocoon.forms.formmodel.Widget;
027: import org.apache.cocoon.forms.formmodel.MultiValueField;
028: import org.apache.cocoon.forms.formmodel.Field;
029: import org.apache.cocoon.forms.validation.ValidationError;
030: import org.apache.cocoon.forms.validation.ValidationErrorAware;
031:
032: import java.util.regex.Matcher;
033:
034: /**
035: * Utility methods for textual editing of link-type fields.
036: */
037: public class LinkFieldHelper {
038: public static VariantKey parseVariantKey(String link,
039: VariantManager variantManager) {
040: Matcher matcher = Constants.DAISY_LINK_PATTERN.matcher(link);
041: if (!matcher.matches())
042: throw new IllegalArgumentException("Invalid link: " + link);
043:
044: String documentId = matcher.group(1);
045: String branchInput = matcher.group(2);
046: String languageInput = matcher.group(3);
047: long branchId, languageId;
048:
049: if (branchInput != null && branchInput.length() > 0) {
050: try {
051: branchId = variantManager.getBranch(branchInput, false)
052: .getId();
053: } catch (RepositoryException e) {
054: throw new RuntimeException(e);
055: }
056: } else {
057: branchId = -1;
058: }
059:
060: if (languageInput != null && languageInput.length() > 0) {
061: try {
062: languageId = variantManager.getLanguage(languageInput,
063: false).getId();
064: } catch (RepositoryException e) {
065: throw new RuntimeException(e);
066: }
067: } else {
068: languageId = -1;
069: }
070:
071: return new VariantKey(documentId, branchId, languageId);
072: }
073:
074: public static String variantKeyToString(VariantKey variantKey,
075: VariantManager variantManager) {
076: StringBuilder text = new StringBuilder(20);
077: text.append("daisy:");
078: text.append(variantKey.getDocumentId());
079: if (variantKey.getBranchId() != -1
080: || variantKey.getLanguageId() != -1) {
081: text.append("@");
082: if (variantKey.getBranchId() != -1) {
083: String branchName;
084: try {
085: branchName = variantManager.getBranch(
086: variantKey.getBranchId(), false).getName();
087: } catch (RepositoryException e) {
088: branchName = String.valueOf(variantKey
089: .getBranchId());
090: }
091: text.append(branchName);
092: }
093: if (variantKey.getLanguageId() != -1) {
094: text.append(":");
095: String languageName;
096: try {
097: languageName = variantManager.getLanguage(
098: variantKey.getLanguageId(), false)
099: .getName();
100: } catch (RepositoryException e) {
101: languageName = String.valueOf(variantKey
102: .getLanguageId());
103: }
104: text.append(languageName);
105: }
106: }
107: return text.toString();
108: }
109:
110: public static boolean validate(Widget widget,
111: boolean isHierarchical, Repository repository) {
112: if (widget.getValue() == null)
113: return true;
114:
115: if (widget instanceof MultiValueField) {
116: Object[] values = (Object[]) widget.getValue();
117: boolean result = true;
118: for (int i = 0; i < values.length; i++) {
119: result = validateLink((String) values[i],
120: isHierarchical, (ValidationErrorAware) widget,
121: repository);
122: if (!result)
123: return result;
124: }
125: return result;
126: } else if (widget instanceof Field) {
127: return validateLink((String) widget.getValue(),
128: isHierarchical, (ValidationErrorAware) widget,
129: repository);
130: } else {
131: throw new RuntimeException("Unexpected type of widget: "
132: + widget.getClass().getName());
133: }
134: }
135:
136: private static boolean validateHierarchicalLink(String link,
137: ValidationErrorAware widget, Repository repository) {
138: String[] parts = HierarchicalFieldHelper
139: .parseHierarchicalInput(link);
140: for (String part : parts) {
141: boolean result = validateLink(part, false, widget,
142: repository);
143: if (!result)
144: return result;
145: }
146: return true;
147: }
148:
149: private static boolean validateLink(String link,
150: boolean isHierarchical, ValidationErrorAware widget,
151: Repository repository) {
152: if (isHierarchical)
153: return validateHierarchicalLink(link, widget, repository);
154:
155: link = link.trim();
156: Matcher matcher = Constants.DAISY_LINK_PATTERN.matcher(link);
157: if (matcher.matches()) {
158: String docId = matcher.group(1);
159: String branchInput = matcher.group(2);
160: String languageInput = matcher.group(3);
161:
162: Matcher docIdMatcher = Constants.DAISY_COMPAT_DOCID_PATTERN
163: .matcher(docId);
164: if (!docIdMatcher.matches()) {
165: widget.setValidationError(new ValidationError(
166: "editdoc.link-no-valid-docid",
167: new String[] { docId }));
168: return false;
169: }
170:
171: // check numeric part of the document ID falls in the long boundaries
172: try {
173: Long.parseLong(docIdMatcher.group(1));
174: } catch (NumberFormatException e) {
175: widget.setValidationError(new ValidationError(
176: "editdoc.link-no-valid-docid",
177: new String[] { docId }));
178: return false;
179: }
180:
181: // check the namespace of the document ID exists
182: String namespace = docIdMatcher.group(2);
183: if (namespace != null) {
184: try {
185: repository.getNamespaceManager().getNamespace(
186: namespace);
187: } catch (NamespaceNotFoundException e) {
188: widget.setValidationError(new ValidationError(
189: "editdoc.link-no-valid-namespace",
190: new String[] { namespace }));
191: return false;
192: }
193: }
194:
195: // test the specified branch and language (if any) exist
196: VariantManager variantManager = repository
197: .getVariantManager();
198: if (branchInput != null && branchInput.length() > 0) {
199: try {
200: variantManager.getBranch(branchInput, false);
201: } catch (BranchNotFoundException e) {
202: widget.setValidationError(new ValidationError(
203: "editdoc.link-no-valid-branch",
204: new String[] { branchInput }));
205: return false;
206: } catch (RepositoryException e) {
207: widget.setValidationError(new ValidationError(
208: "Error testing branch existence: "
209: + e.toString(), false));
210: return false;
211: }
212: }
213:
214: if (languageInput != null && languageInput.length() > 0) {
215: try {
216: variantManager.getLanguage(languageInput, false);
217: } catch (LanguageNotFoundException e) {
218: widget.setValidationError(new ValidationError(
219: "editdoc.link-no-valid-language",
220: new String[] { languageInput }));
221: return false;
222: } catch (RepositoryException e) {
223: widget.setValidationError(new ValidationError(
224: "Error testing language existence: "
225: + e.toString()));
226: return false;
227: }
228: }
229: } else {
230: widget.setValidationError(new ValidationError(
231: "editdoc.link-not-valid", new String[] { link }));
232: return false;
233: }
234: return true;
235: }
236: }
|