Package org.odftoolkit.odfvalidator

Source Code of org.odftoolkit.odfvalidator.ODFPackageValidator

/************************************************************************
*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER
*
* Copyright 2008, 2010 Oracle and/or its affiliates. All rights reserved.
*
* Use is subject to license terms.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy
* of the License at http://www.apache.org/licenses/LICENSE-2.0. You can also
* obtain a copy of the License at http://odftoolkit.org/docs/license.txt
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
* See the License for the specific language governing permissions and
* limitations under the License.
*
************************************************************************/
package org.odftoolkit.odfvalidator;

import java.io.IOException;
import java.io.InputStream;
import java.io.PrintStream;
import java.util.Iterator;
import java.util.Set;
import java.util.zip.ZipException;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
import javax.xml.transform.sax.SAXSource;
import javax.xml.validation.Validator;
import org.odftoolkit.odfdom.doc.OdfDocument;
import org.odftoolkit.odfdom.pkg.OdfPackage;
import org.odftoolkit.odfdom.pkg.manifest.EncryptionDataElement;
import org.odftoolkit.odfdom.pkg.manifest.OdfFileEntry;
import org.xml.sax.InputSource;
import org.xml.sax.XMLFilter;
import org.xml.sax.XMLReader;

import org.xml.sax.helpers.DefaultHandler;

/**
* Validator for Files
*/
abstract class ODFPackageValidator {

  static final String DOCUMENT_SETTINGS = "document-settings";
  static final String DOCUMENT_STYLES = "document-styles";
  static final String DOCUMENT_CONTENT = "document-content";
  protected Logger.LogLevel m_nLogLevel;
  protected OdfValidatorMode m_eMode = OdfValidatorMode.CONFORMANCE;
  protected SAXParseExceptionFilter m_aFilter = null;
  protected ODFValidatorProvider m_aValidatorProvider = null;
  protected ODFValidationResult m_aResult = null;
  protected OdfVersion m_aConfigVersion = null;
  private SAXParserFactory m_aSAXParserFactory = null;
  protected OdfVersion mOdfPackageVersion = null;

  protected ODFPackageValidator(Logger.LogLevel nLogLevel, OdfValidatorMode eMode, OdfVersion aVersion,
      SAXParseExceptionFilter aFilter, ODFValidatorProvider aValidatorProvider) {
    m_nLogLevel = nLogLevel;
    m_eMode = eMode;
    m_aFilter = aFilter;
    m_aValidatorProvider = aValidatorProvider;
    m_aConfigVersion = aVersion;
    m_aResult = new ODFValidationResult(aVersion, eMode);
  }

  protected abstract String getLoggerName();

  protected abstract String getDocumentPath();

  protected abstract OdfPackage getPackage(Logger aLogger);

  protected abstract String getStreamName(String aEntry);

  protected boolean validate(PrintStream aOut) throws ODFValidatorException {
    Logger aLogger =
        new Logger(getLoggerName(), getDocumentPath(), aOut, m_nLogLevel);
    return _validate(aLogger);
  }

  protected boolean validate(Logger aParentLogger) throws ODFValidatorException {
    Logger aLogger =
        new Logger(getDocumentPath(), aParentLogger);
    return _validate(aLogger);
  }

 
  OdfVersion getOdfPackageVersion(){
    return mOdfPackageVersion;
  }
 
  private boolean _validate(Logger aLogger) throws ODFValidatorException {
    boolean bHasErrors = false;

    OdfPackage aPkg = getPackage(aLogger);
    if (aPkg == null) {
      return true;
    }

    try {
      String aDocVersion = getVersion(aLogger);
      if (aDocVersion != null) {
        aLogger.logInfo("ODF version of root document: " + aDocVersion, false);
        mOdfPackageVersion = OdfVersion.valueOf(aDocVersion, true);
      }
      OdfVersion aVersion = m_aConfigVersion == null ? OdfVersion.valueOf(aDocVersion, true) : m_aConfigVersion;

      bHasErrors |= validatePre(aLogger, aVersion);
      aLogger.logInfo("Media Type: " + m_aResult.getMediaType(), false);

      bHasErrors |= validateMeta(aLogger, getStreamName(OdfDocument.OdfXMLFile.META.getFileName()), aVersion, true);
      bHasErrors |= validateEntry(aLogger, getStreamName(OdfDocument.OdfXMLFile.SETTINGS.getFileName()), DOCUMENT_SETTINGS, aVersion);
      bHasErrors |= validateEntry(aLogger, getStreamName(OdfDocument.OdfXMLFile.STYLES.getFileName()), DOCUMENT_STYLES, aVersion);
      if (m_aResult.getMediaType().equals(ODFMediaTypes.FORMULA_MEDIA_TYPE)) {
        bHasErrors |= validateMathML(aLogger, getStreamName(OdfDocument.OdfXMLFile.CONTENT.getFileName()), aVersion);
      } else {
        bHasErrors |= validateEntry(aLogger, getStreamName(OdfDocument.OdfXMLFile.CONTENT.getFileName()), DOCUMENT_CONTENT, aVersion);
      }
      bHasErrors |= validatePost(aLogger, aVersion);
    } catch (ZipException e) {
      aLogger.logFatalError(e.getMessage());
    } catch (IOException e) {
      aLogger.logFatalError(e.getMessage());
    }

    logSummary(bHasErrors, aLogger);

    return bHasErrors || aLogger.hasError();
  }

  protected boolean validatePre(Logger aLogger, OdfVersion aVersion) throws ODFValidatorException, IOException {
    return false;
  }

  protected boolean validatePost(Logger aLogger, OdfVersion aVersion) throws ODFValidatorException, IOException {
    return false;
  }

  protected void logSummary(boolean bHasErrors, Logger aLogger) {
  }

  protected boolean validateEntry(Logger aParentLogger, String aEntryName, String aLocalElementName, OdfVersion aVersion) throws IOException, ZipException, IllegalStateException, ODFValidatorException {
    Logger aLogger = new Logger(aEntryName, aParentLogger);
    XMLFilter aFilter = new ContentFilter(aLogger, aLocalElementName);
    if ((m_eMode == OdfValidatorMode.CONFORMANCE && aVersion.compareTo(OdfVersion.V1_1) <= 0)
        || m_eMode == OdfValidatorMode.EXTENDED_CONFORMANCE) {
      XMLFilter aAlienFilter = new ForeignContentFilter(aLogger, aVersion, m_aResult);
      aAlienFilter.setParent(aFilter);
      aFilter = aAlienFilter;
    }
    Validator aValidator = null;
    if (m_eMode == OdfValidatorMode.VALIDATE_STRICT) {
      aValidator = m_aValidatorProvider.getStrictValidator(aParentLogger.getOutputStream(), aVersion);
    } else {
      aValidator = m_aValidatorProvider.getValidator(aParentLogger.getOutputStream(), aVersion);
    }
//    Validator aValidator = m_eMode == OdfValidatorMode.VALIDATE_STRICT ? m_aValidatorProvider.getStrictValidator(aParentLogger.getOutputStream(), aVersion)
//        : m_aValidatorProvider.getValidator(aParentLogger.getOutputStream(), aVersion);
    return validateEntry(aFilter, aValidator, aLogger, aEntryName);
  }

  private boolean validateMeta(Logger aParentLogger, String aEntryName, OdfVersion aVersion, boolean bIsRoot) throws IOException, ZipException, IllegalStateException, ODFValidatorException {
    Logger aLogger = new Logger(aEntryName, aParentLogger);
    XMLFilter aFilter = new MetaFilter(aLogger, m_aResult);
    if ((m_eMode == OdfValidatorMode.CONFORMANCE && aVersion.compareTo(OdfVersion.V1_1) <= 0)
        || m_eMode == OdfValidatorMode.EXTENDED_CONFORMANCE) {
      XMLFilter aAlienFilter = new ForeignContentFilter(aLogger, aVersion, m_aResult);
      aAlienFilter.setParent(aFilter);
      aFilter = aAlienFilter;
    }

    Validator aValidator = null;
    if (m_eMode == OdfValidatorMode.VALIDATE_STRICT) {
      aValidator = m_aValidatorProvider.getStrictValidator(aParentLogger.getOutputStream(), aVersion);
    } else {
      aValidator = m_aValidatorProvider.getValidator(aParentLogger.getOutputStream(), aVersion);
    }
    return validateEntry(aFilter, aValidator, aLogger, aEntryName);
  }

  private boolean validateMathML(Logger aParentLogger, String aEntryName, OdfVersion aVersion) throws IOException, ZipException, IllegalStateException, ODFValidatorException {
    Logger aLogger = new Logger(aEntryName, aParentLogger);
    String aMathMLDTDSystemId = m_aValidatorProvider.getMathMLDTDSystemId(aVersion);
    if (aMathMLDTDSystemId != null) {
      // validate using DTD
      return parseEntry(new MathML101Filter(aMathMLDTDSystemId, aLogger), aLogger, aEntryName, true);
    } else {
      Validator aMathMLValidator = m_aValidatorProvider.getMathMLValidator(aParentLogger.getOutputStream(), null);
      if (aMathMLValidator == null) {
        aLogger.logInfo("MathML schema is not available. Validation has been skipped.", false);
        return false;
      }
      return validateEntry(new MathML20Filter(aLogger), aMathMLValidator, aLogger, aEntryName);
    }
  }

  protected boolean validateDSig(Logger aParentLogger, String aEntryName, OdfVersion aVersion) throws IOException, ZipException, IllegalStateException, ODFValidatorException {
    Validator aValidator = m_aValidatorProvider.getDSigValidator(aParentLogger.getOutputStream(), aVersion);
    Logger aLogger = new Logger(aEntryName, aParentLogger);
    if (aValidator == null) {
      aLogger.logWarning("Signature not validated because there is no Signature Validator configured for the selected Configuration");
      return false;
    }

    return validateEntry(new DSigFilter(aLogger), aValidator, aLogger, aEntryName);
  }

  protected boolean validateEntry(XMLFilter aFilter,
      Validator aValidator, Logger aLogger,
      String aEntryName) throws IOException, ZipException, IllegalStateException, ODFValidatorException {
    OdfPackage aPkg = getPackage(aLogger);

    if (!aEntryName.equals(OdfPackage.OdfFile.MANIFEST.getPath()) && isEncrypted(aEntryName, aLogger)) {
      return false;
    }

    InputStream aInStream = null;
    try {
      aInStream = aPkg.getInputStream(aEntryName, true);
    } catch (Exception e) {
      throw new ODFValidatorException(e);
    }


    if (aValidator == null) {

      aLogger.logWarning("no Validator configured in selected Configuration for this file type");
      return false;
    }



    return aInStream != null ? validate(aInStream, aFilter, aValidator, aLogger) : false;
  }

  private boolean validate(InputStream aInStream,
      XMLFilter aFilter,
      javax.xml.validation.Validator aValidator,
      Logger aLogger) throws ODFValidatorException {
    SAXParser aParser = getSAXParser(false);
    SchemaErrorHandler aErrorHandler = new SchemaErrorHandler(aLogger, m_aFilter);

    try {
      XMLReader aReader;
      if (aFilter != null) {
        XMLReader aParent = aFilter.getParent();
        if (aParent != null) {
          ((XMLFilter) aParent).setParent(aParser.getXMLReader());
        } else {
          aFilter.setParent(aParser.getXMLReader());
        }
        aReader = aFilter;
      } else {
        aReader = aParser.getXMLReader();
      }

      if (m_aFilter != null) {
        m_aFilter.startSubFile();
      }
      aValidator.setErrorHandler(aErrorHandler);
      try {
        aValidator.validate(new SAXSource(aReader,
            new InputSource(aInStream)));
      } catch (RuntimeException e) {
        aLogger.logFatalError(e.getMessage());
        m_aValidatorProvider.resetValidatorProvider();
      }
    } catch (org.xml.sax.SAXParseException e) {
      aErrorHandler.fatalErrorNoException(e);
    } catch (org.xml.sax.SAXException e) {
      aLogger.logFatalError(e.getMessage());
    } catch (IOException e) {
      aLogger.logFatalError(e.getMessage());
    }

    aLogger.logSummaryInfo();
    if (m_aResult.hasForeignElements()) {
      Set<String> aForeignElementURISet = m_aResult.getForeignElements().keySet();
      StringBuilder aBuffer = new StringBuilder();
      Iterator<String> aIter = aForeignElementURISet.iterator();
      boolean bFirst = true;
      while (aIter.hasNext()) {
        String aURI = aIter.next();
        aBuffer.setLength(0);
        aBuffer.append(m_aResult.getForeignElements().get(aURI));
        aBuffer.append(" extension elements from the following namespace were found: ");
        aBuffer.append(aURI);
        aLogger.logInfo(aBuffer.toString(), false);
      }
    }
    if (m_aResult.hasForeignAttributes()) {
      Set<String> aForeignAttributeURISet = m_aResult.getForeignAttributes().keySet();
      Iterator<String> aIter = aForeignAttributeURISet.iterator();
      StringBuilder aBuffer = new StringBuilder();
      while (aIter.hasNext()) {
        String aURI = aIter.next();
        aBuffer.setLength(0);
        aBuffer.append(m_aResult.getForeignAttributes().get(aURI));
        aBuffer.append(" extension attributes from the following namespace were found: ");
        aBuffer.append(aURI);
        aLogger.logInfo(aBuffer.toString(), false);
      }
    }
    return aLogger.hasError();
  }

  protected boolean parseEntry(XMLFilter aFilter,
      Logger aLogger,
      String aEntryName, boolean bValidating) throws IOException, ZipException, IllegalStateException, ODFValidatorException {
    OdfPackage aPkg = getPackage(aLogger);

    if (isEncrypted(aEntryName, aLogger)) {
      return false;
    }

    InputStream aInStream = null;
    try {
      aInStream = getPackage(aLogger).getInputStream(aEntryName, true);
    } catch (Exception e) {
      throw new ODFValidatorException(e);
    }

    return aInStream != null ? parse(aInStream, aFilter, bValidating, aLogger) : false;
  }

  private boolean parse(InputStream aInStream, XMLFilter aFilter, boolean bValidating, Logger aLogger) throws ODFValidatorException {
    SAXParser aParser = getSAXParser(bValidating);
    SchemaErrorHandler aErrorHandler = new SchemaErrorHandler(aLogger, m_aFilter);

    try {
      XMLReader aReader;
      if (aFilter != null) {
        aFilter.setParent(aParser.getXMLReader());
        aReader = aFilter;
      } else {
        aReader = aParser.getXMLReader();
      }
      if (m_aFilter != null) {
        m_aFilter.startSubFile();
      }
      aReader.setErrorHandler(aErrorHandler);
      aReader.parse(new InputSource(aInStream));
    } catch (org.xml.sax.SAXParseException e) {
      aErrorHandler.fatalErrorNoException(e);
    } catch (org.xml.sax.SAXException e) {
      aLogger.logFatalError(e.getMessage());
    } catch (IOException e) {
      aLogger.logFatalError(e.getMessage());
    }

    if (bValidating) {
      aLogger.logSummaryInfo();
    }
    return aLogger.hasError();
  }

  private boolean isEncrypted(String aEntryName, Logger aLogger) {
    OdfFileEntry aFileEntry = getPackage(aLogger).getFileEntry(aEntryName);
    if (aFileEntry != null) {
      EncryptionDataElement aEncData = aFileEntry.getEncryptionData();
      if (aEncData != null) {
        aLogger.logFatalError("stream content is encrypted. Validataion of encrypted content is not supported.");
        return true;
      }
    }
    return false;
  }

  private SAXParser getSAXParser(boolean bValidating) throws ODFValidatorException {
    SAXParser aParser = null;
    if (m_aSAXParserFactory == null) {
      m_aSAXParserFactory = SAXParserFactory.newInstance();
      m_aSAXParserFactory.setNamespaceAware(true);
    }

    try {
      m_aSAXParserFactory.setValidating(bValidating);
      aParser = m_aSAXParserFactory.newSAXParser();
    } catch (javax.xml.parsers.ParserConfigurationException e) {
      throw new ODFValidatorException(e);
    } catch (org.xml.sax.SAXException e) {
      throw new ODFValidatorException(e);
    }

    return aParser;
  }

  /**
   * get the generator
   */
  public String getGenerator() {
    return m_aResult.getGenerator();
  }

  private String getVersion(Logger aLogger) throws ODFValidatorException {
    String aVersion = null;

    InputStream aInStream = null;
    try {
      OdfPackage aPkg = getPackage(aLogger);
      aInStream = aPkg.getInputStream(getStreamName(OdfDocument.OdfXMLFile.META.getFileName()), true);
      if (aInStream == null) {
        aInStream = aPkg.getInputStream(getStreamName(OdfDocument.OdfXMLFile.SETTINGS.getFileName()), true);
      }
      if (aInStream == null) {
        aInStream = aPkg.getInputStream(getStreamName(OdfDocument.OdfXMLFile.CONTENT.getFileName()), true);
      }
      if (aInStream == null) {
        return null;
      }
    } catch (Exception e) {
      aLogger.logFatalError(e.getMessage());
    }

    SAXParser aParser = getSAXParser(false);

    DefaultHandler aHandler = new VersionHandler();

    try {
      aParser.parse(aInStream, aHandler);
    } catch (SAXVersionException e) {
      aVersion = e.getVersion();
    } catch (org.xml.sax.SAXException e) {
      aLogger.logFatalError(e.getMessage());
    } catch (IOException e) {
      aLogger.logFatalError(e.getMessage());
    }

    return aVersion;
  }
}
TOP

Related Classes of org.odftoolkit.odfvalidator.ODFPackageValidator

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.