001: package net.sf.saxon.style;
002:
003: import net.sf.saxon.Configuration;
004: import net.sf.saxon.expr.Expression;
005: import net.sf.saxon.expr.ExpressionTool;
006: import net.sf.saxon.instruct.CopyOf;
007: import net.sf.saxon.instruct.Executable;
008: import net.sf.saxon.om.AttributeCollection;
009: import net.sf.saxon.om.Validation;
010: import net.sf.saxon.trans.XPathException;
011: import net.sf.saxon.type.SchemaType;
012:
013: /**
014: * An xsl:copy-of element in the stylesheet. <br>
015: */
016:
017: public final class XSLCopyOf extends StyleElement {
018:
019: private Expression select;
020: private boolean copyNamespaces;
021: private int validation = Validation.PRESERVE;
022: private SchemaType schemaType;
023: private boolean readOnce = false; // extension attribute to enable serial processing
024:
025: /**
026: * Determine whether this node is an instruction.
027: * @return true - it is an instruction
028: */
029:
030: public boolean isInstruction() {
031: return true;
032: }
033:
034: public void prepareAttributes() throws XPathException {
035:
036: AttributeCollection atts = getAttributeList();
037: String selectAtt = null;
038: String copyNamespacesAtt = null;
039: String validationAtt = null;
040: String typeAtt = null;
041: String readOnceAtt = null;
042:
043: for (int a = 0; a < atts.getLength(); a++) {
044: int nc = atts.getNameCode(a);
045: String f = getNamePool().getClarkName(nc);
046: if (f == StandardNames.SELECT) {
047: selectAtt = atts.getValue(a);
048: } else if (f == StandardNames.COPY_NAMESPACES) {
049: copyNamespacesAtt = atts.getValue(a).trim();
050: } else if (f == StandardNames.VALIDATION) {
051: validationAtt = atts.getValue(a).trim();
052: } else if (f == StandardNames.TYPE) {
053: typeAtt = atts.getValue(a).trim();
054: } else if (f == StandardNames.SAXON_READ_ONCE) {
055: readOnceAtt = atts.getValue(a).trim();
056: } else {
057: checkUnknownAttribute(nc);
058: }
059: }
060:
061: if (selectAtt != null) {
062: select = makeExpression(selectAtt);
063: } else {
064: reportAbsence("select");
065: }
066:
067: if (copyNamespacesAtt == null) {
068: copyNamespaces = true;
069: } else {
070: if (copyNamespacesAtt.equals("yes")) {
071: copyNamespaces = true;
072: } else if (copyNamespacesAtt.equals("no")) {
073: copyNamespaces = false;
074: } else {
075: compileError(
076: "Value of copy-namespaces must be 'yes' or 'no'",
077: "XTSE0020");
078: }
079: }
080:
081: if (validationAtt != null) {
082: validation = Validation.getCode(validationAtt);
083: if (validation != Validation.STRIP
084: && !getConfiguration().isSchemaAware(
085: Configuration.XSLT)) {
086: compileError(
087: "To perform validation, a schema-aware XSLT processor is needed",
088: "XTSE1660");
089: }
090: if (validation == Validation.INVALID) {
091: compileError("invalid value of validation attribute",
092: "XTSE0020");
093: }
094: } else {
095: validation = getContainingStylesheet()
096: .getDefaultValidation();
097: }
098:
099: if (typeAtt != null) {
100: schemaType = getSchemaType(typeAtt);
101: if (!getConfiguration().isSchemaAware(Configuration.XSLT)) {
102: compileError(
103: "The @type attribute is available only with a schema-aware XSLT processor",
104: "XTSE1660");
105: }
106: }
107:
108: if (typeAtt != null && validationAtt != null) {
109: compileError(
110: "The @validation and @type attributes are mutually exclusive",
111: "XTSE1505");
112: }
113:
114: if (validation == Validation.PRESERVE && !copyNamespaces) {
115: compileError(
116: "copy-namespaces must be set to 'yes' when validation is set to 'preserve'",
117: "XTSE0950");
118: }
119:
120: if (readOnceAtt != null) {
121: if (readOnceAtt.equals("yes")) {
122: readOnce = true;
123: } else if (readOnceAtt.equals("no")) {
124: readOnce = false;
125: } else {
126: compileError("saxon:read-once attribute must be 'yes' or 'no'");
127: }
128: }
129: }
130:
131: public void validate() throws XPathException {
132: checkWithinTemplate();
133: checkEmpty();
134: select = typeCheck("select", select);
135: }
136:
137: public Expression compile(Executable exec) {
138: CopyOf inst = new CopyOf(select, copyNamespaces, validation,
139: schemaType, false);
140: if (readOnce) {
141: inst.setReadOnce(readOnce);
142: }
143: ExpressionTool.makeParentReferences(inst);
144: return inst;
145: }
146:
147: }
148:
149: //
150: // The contents of this file are subject to the Mozilla Public License Version 1.0 (the "License");
151: // you may not use this file except in compliance with the License. You may obtain a copy of the
152: // License at http://www.mozilla.org/MPL/
153: //
154: // Software distributed under the License is distributed on an "AS IS" basis,
155: // WITHOUT WARRANTY OF ANY KIND, either express or implied.
156: // See the License for the specific language governing rights and limitations under the License.
157: //
158: // The Original Code is: all this file.
159: //
160: // The Initial Developer of the Original Code is Michael H. Kay.
161: //
162: // Portions created by (your name) are Copyright (C) (your legal entity). All Rights Reserved.
163: //
164: // Contributor(s): none.
165: //
|