| /** |
| * ********************************************************************** |
| * |
| * 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.PrintWriter; |
| import java.io.StringWriter; |
| import java.util.ArrayList; |
| import java.util.Iterator; |
| import java.util.zip.ZipException; |
| import javax.xml.validation.Validator; |
| import org.odftoolkit.odfdom.doc.OdfDocument; |
| import org.odftoolkit.odfdom.pkg.OdfPackage; |
| import org.xml.sax.ErrorHandler; |
| |
| abstract class ODFRootPackageValidator extends ODFPackageValidator implements ManifestEntryListener { |
| |
| private OdfPackage m_aPkg = null; |
| private ArrayList<ManifestEntry> m_aSubDocs = null; |
| private ODFPackageErrorHandler m_ErrorHandler = null; |
| |
| protected ODFRootPackageValidator(Logger.LogLevel nLogLevel, OdfValidatorMode eMode, OdfVersion aVersion, SAXParseExceptionFilter aFilter, ODFValidatorProvider aValidatorProvider) { |
| super(nLogLevel, eMode, aVersion, aFilter, aValidatorProvider); |
| } |
| |
| protected abstract OdfPackage getPackage(ErrorHandler handler) throws Exception; |
| |
| protected OdfPackage getPackage(Logger aLogger) { |
| if (m_aPkg == null) { |
| try { |
| m_ErrorHandler = new ODFPackageErrorHandler(); |
| m_aPkg = getPackage(m_ErrorHandler); |
| // for additional mimetype checking, load root document |
| try { |
| OdfDocument.loadDocument(m_aPkg, ""); |
| } catch (Exception e) { |
| // ignore -- the interesting stuff is passed to handler |
| } |
| } catch (IOException e) { |
| if (e.getMessage().startsWith("only DEFLATED entries can have EXT descriptor")) { |
| aLogger.logFatalError("The document is encrypted. Validation of encrypted documents is not supported."); |
| } else { |
| aLogger.logFatalError(e.getMessage()); |
| } |
| } catch (Exception e) { |
| StringWriter errors = new StringWriter(); |
| e.printStackTrace(new PrintWriter(errors)); |
| aLogger.logFatalError(e.getMessage() + "\n" + errors.toString()); |
| } |
| } |
| return m_aPkg; |
| } |
| |
| protected String getStreamName(String aEntry) { |
| return aEntry; |
| } |
| |
| @Override |
| protected boolean validatePre(Logger aLogger, OdfVersion aVersion) throws ODFValidatorException, IOException { |
| Logger aManifestLogger = new Logger(OdfPackage.OdfFile.MANIFEST.getPath(), aLogger); |
| Logger aMimetypeLogger = new Logger("mimetype", aLogger); |
| |
| // UGLY: do something that causes ODFDOM to parse the manifest, which |
| // may cause m_ErrorHandler to be called |
| m_aPkg.getFilePaths(); |
| // hack: just create logger again, too lazy to create a Pair class |
| // and return it from validateMimetype... |
| boolean bErrorsFound = m_ErrorHandler.processErrors(aLogger, aManifestLogger, |
| aMimetypeLogger, aVersion); |
| |
| bErrorsFound |= validateMimetype(aMimetypeLogger, aVersion); |
| bErrorsFound |= validateManifest(aManifestLogger, aVersion); |
| aMimetypeLogger.logSummaryInfo(); |
| |
| return bErrorsFound; |
| } |
| |
| @Override |
| protected boolean validatePost(Logger aLogger, OdfVersion aVersion) throws ODFValidatorException, IOException { |
| boolean bHasErrors = false; |
| if (m_aSubDocs != null) { |
| Iterator<ManifestEntry> aIter = m_aSubDocs.iterator(); |
| while (aIter.hasNext()) { |
| ManifestEntry aEntry = aIter.next(); |
| ODFPackageValidator aPackageValidator |
| = new ODFSubPackageValidator(getPackage(aLogger), getLoggerName(), aEntry.getFullPath(), aEntry.getMediaType(), |
| m_nLogLevel, m_eMode, m_aConfigVersion, m_aFilter, m_aResult.getGenerator(), m_aValidatorProvider); |
| bHasErrors |= aPackageValidator.validate(aLogger); |
| } |
| } |
| |
| if (aVersion.compareTo(OdfVersion.V1_2) >= 0) { |
| bHasErrors |= validateDSig(aLogger, OdfPackageExt.STREAMNAME_DOCUMENT_SIGNATURES, aVersion); |
| bHasErrors |= validateDSig(aLogger, OdfPackageExt.STREAMNAME_MACRO_SIGNATURES, aVersion); |
| } |
| |
| return bHasErrors; |
| } |
| |
| @Override |
| protected void logSummary(boolean bHasErrors, Logger aLogger) { |
| aLogger.logSummaryInfo(); |
| if ((bHasErrors || aLogger.hasError()) && m_nLogLevel.compareTo(Logger.LogLevel.INFO) < 0) { |
| aLogger.logInfo("Generator: " + m_aResult.getGenerator(), true); |
| } |
| } |
| |
| public void foundManifestEntry(ManifestEntry aManifestEntry) { |
| if (aManifestEntry.isOpenDocumentMediaType()) { |
| if (m_aSubDocs == null) { |
| m_aSubDocs = new ArrayList<ManifestEntry>(); |
| } |
| m_aSubDocs.add(aManifestEntry); |
| } |
| } |
| |
| private boolean validateMimetype(Logger aLogger, OdfVersion aVersion) { |
| boolean bHasErrors = false; |
| |
| String aMimetype = getPackage(aLogger).getMediaTypeString(); |
| if ((aMimetype == null) || aMimetype.length() == 0) { |
| aLogger.logFatalError("file is not a zip file, or has no mimetype."); |
| bHasErrors = true; |
| } else if (!(aMimetype.equals(ODFMediaTypes.TEXT_MEDIA_TYPE) |
| || aMimetype.equals(ODFMediaTypes.TEXT_TEMPLATE_MEDIA_TYPE) |
| || aMimetype.equals(ODFMediaTypes.GRAPHICS_MEDIA_TYPE) |
| || aMimetype.equals(ODFMediaTypes.GRAPHICS_TEMPLATE_MEDIA_TYPE) |
| || aMimetype.equals(ODFMediaTypes.PRESENTATION_MEDIA_TYPE) |
| || aMimetype.equals(ODFMediaTypes.SPREADSHEET_MEDIA_TYPE) |
| || aMimetype.equals(ODFMediaTypes.SPREADSHEET_TEMPLATE_MEDIA_TYPE) |
| || aMimetype.equals(ODFMediaTypes.CHART_MEDIA_TYPE) |
| || aMimetype.equals(ODFMediaTypes.CHART_TEMPLATE_MEDIA_TYPE) |
| || aMimetype.equals(ODFMediaTypes.IMAGE_MEDIA_TYPE) |
| || aMimetype.equals(ODFMediaTypes.IMAGE_TEMPLATE_MEDIA_TYPE) |
| || aMimetype.equals(ODFMediaTypes.FORMULA_MEDIA_TYPE) |
| || aMimetype.equals(ODFMediaTypes.FORMULA_TEMPLATE_MEDIA_TYPE) |
| || aMimetype.equals(ODFMediaTypes.TEXT_MASTER_MEDIA_TYPE) |
| || aMimetype.equals(ODFMediaTypes.TEXT_WEB_MEDIA_TYPE))) { |
| aLogger.logInfo("mimetype is not an ODFMediaTypes mimetype.", false); |
| bHasErrors = true; |
| } |
| |
| return bHasErrors; |
| } |
| |
| private boolean validateManifest(Logger aLogger, OdfVersion aVersion) throws IOException, ZipException, IllegalStateException, ODFValidatorException { |
| boolean bRet; |
| ManifestFilter aFilter = new ManifestFilter(aLogger, m_aResult, this); |
| Validator aManifestValidator = m_aValidatorProvider.getManifestValidator(aLogger.getOutputStream(), aVersion); |
| if (aManifestValidator != null) { |
| bRet = validateEntry(aFilter, |
| aManifestValidator, aLogger, OdfPackage.OdfFile.MANIFEST.getPath()); |
| } else { |
| aLogger.logInfo("Validation of " + OdfPackage.OdfFile.MANIFEST.getPath() + " skipped.", false); |
| bRet = parseEntry(aFilter, aLogger, OdfPackage.OdfFile.MANIFEST.getPath(), false); |
| } |
| return bRet; |
| } |
| |
| } |