001/*
002 * Licensed to the Apache Software Foundation (ASF) under one
003 * or more contributor license agreements.  See the NOTICE file
004 * distributed with this work for additional information
005 * regarding copyright ownership.  The ASF licenses this file
006 * to you under the Apache License, Version 2.0 (the
007 * "License"); you may not use this file except in compliance
008 * with the License.  You may obtain a copy of the License at
009 *
010 *     http://www.apache.org/licenses/LICENSE-2.0
011 *
012 * Unless required by applicable law or agreed to in writing, software
013 * distributed under the License is distributed on an "AS IS" BASIS,
014 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
015 * See the License for the specific language governing permissions and
016 * limitations under the License.
017 */
018
019package org.fcrepo.jena;
020
021import java.io.PrintWriter;
022
023import org.apache.jena.rdf.model.* ;
024import org.apache.jena.rdf.model.impl.Util ;
025import org.apache.jena.vocabulary.RDFSyntax ;
026
027/** Writes out an XML serialization of a model.
028 */
029public class CopyOfBasic extends CopyOfBaseXMLWriter
030{
031    public CopyOfBasic()
032    {}
033
034    private String space;
035
036    @Override protected void writeBody
037            ( Model model, PrintWriter pw, String base, boolean inclXMLBase )
038    {
039        setSpaceFromTabCount();
040        writeRDFHeader( model, pw );
041        writeRDFStatements( model, pw );
042        writeRDFTrailer( pw, base );
043        pw.flush();
044    }
045
046    private void setSpaceFromTabCount()
047    {
048        space = "";
049        for (int i=0; i < tabSize; i += 1) space += " ";
050    }
051
052    protected void writeSpace( PrintWriter writer )
053    { writer.print( space ); }
054
055    private void writeRDFHeader(Model model, PrintWriter writer)
056    {
057        String xmlns = xmlnsDecl();
058        writer.print( "<" + rdfEl( "RDF" ) + xmlns );
059        if (null != xmlBase && xmlBase.length() > 0)
060            writer.print( "\n  xml:base=" + substitutedAttribute( xmlBase ) );
061        writer.println( " > " );
062    }
063
064    protected void writeRDFStatements( Model model, PrintWriter writer )
065    {
066        ResIterator rIter = model.listSubjects();
067        while (rIter.hasNext()) writeRDFStatements( model, rIter.nextResource(), writer );
068    }
069
070    protected void writeRDFTrailer( PrintWriter writer, String base )
071    { writer.println( "</" + rdfEl( "RDF" ) + ">" ); }
072
073    protected void writeRDFStatements
074            ( Model model, Resource subject, PrintWriter writer )
075    {
076        StmtIterator sIter = model.listStatements( subject, null, (RDFNode) null );
077        writeDescriptionHeader( subject, writer );
078        while (sIter.hasNext()) writePredicate( sIter.nextStatement(), writer );
079        writeDescriptionTrailer( subject, writer );
080    }
081
082    protected void writeDescriptionHeader( Resource subject, PrintWriter writer)
083    {
084        writer.print( space + "<" + rdfEl( "Description" ) + " " );
085        writeResourceId( subject, writer );
086        writer.println( ">" );
087    }
088
089    protected void writePredicate(Statement stmt, final PrintWriter writer)
090    {
091        final Property predicate = stmt.getPredicate();
092        final RDFNode object = stmt.getObject();
093
094        writer.print(space+space+
095                "<"
096                + startElementTag(
097                predicate.getNameSpace(),
098                predicate.getLocalName()));
099
100        if (object instanceof Resource) {
101            writer.print(" ");
102            writeResourceReference(((Resource) object), writer);
103            writer.println("/>");
104        } else {
105            writeLiteral((Literal) object, writer);
106            writer.println(
107                    "</"
108                            + endElementTag(
109                            predicate.getNameSpace(),
110                            predicate.getLocalName())
111                            + ">");
112        }
113    }
114
115    @Override protected void unblockAll()
116    { blockLiterals = false; }
117
118    // NOTE, Fedora change: private -> protected
119    protected boolean blockLiterals = false;
120
121    @Override protected void blockRule( Resource r ) {
122        if (r.equals( RDFSyntax.parseTypeLiteralPropertyElt )) {
123            //       System.err.println("Blocking");
124            blockLiterals = true;
125        } else
126            logger.warn("Cannot block rule <"+r.getURI()+">");
127    }
128
129    protected void writeDescriptionTrailer( Resource subject, PrintWriter writer )
130    { writer.println( space + "</" + rdfEl( "Description" ) + ">" ); }
131
132
133    protected void writeResourceId( Resource r, PrintWriter writer )
134    {
135        if (r.isAnon()) {
136            writer.print(rdfAt("nodeID") + "=" + attributeQuoted(anonId(r)));
137        } else {
138            writer.print(
139                    rdfAt("about")
140                            + "="
141                            + substitutedAttribute(relativize(r.getURI())));
142        }
143    }
144
145    protected void writeResourceReference( Resource r, PrintWriter writer )
146    {
147        if (r.isAnon()) {
148            writer.print(rdfAt("nodeID") + "=" + attributeQuoted(anonId(r)));
149        } else {
150            writer.print(
151                    rdfAt("resource")
152                            + "="
153                            + substitutedAttribute(relativize(r.getURI())));
154        }
155    }
156
157    protected void writeLiteral( Literal l, PrintWriter writer ) {
158        String lang = l.getLanguage();
159        String form = l.getLexicalForm();
160        if (Util.isLangString(l)) {
161            writer.print(" xml:lang=" + attributeQuoted( lang ));
162        } else if (l.isWellFormedXML() && !blockLiterals) {
163            // RDF XML Literals inline.
164            writer.print(" " + rdfAt("parseType") + "=" + attributeQuoted( "Literal" )+">");
165            writer.print( form );
166            return ;
167        } else {
168            // Datatype (if not xsd:string and RDF 1.1)
169            String dt = l.getDatatypeURI();
170            if ( ! Util.isSimpleString(l) )
171                writer.print( " " + rdfAt( "datatype" ) + "=" + substitutedAttribute( dt ) );
172        }
173        // Content.
174        writer.print(">");
175        writer.print( Util.substituteEntitiesInElementContent( form ) );
176    }
177
178}