001    /**
002     * Copyright (c) 2010 Yahoo! Inc. All rights reserved.
003     * Licensed under the Apache License, Version 2.0 (the "License");
004     * you may not use this file except in compliance with the License.
005     * You may obtain a copy of the License at
006     *
007     *   http://www.apache.org/licenses/LICENSE-2.0
008     *
009     *  Unless required by applicable law or agreed to in writing, software
010     *  distributed under the License is distributed on an "AS IS" BASIS,
011     *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
012     *  See the License for the specific language governing permissions and
013     *  limitations under the License. See accompanying LICENSE file.
014     */
015    package org.apache.oozie.service;
016    
017    import org.apache.hadoop.conf.Configuration;
018    import org.apache.oozie.util.IOUtils;
019    import org.apache.oozie.ErrorCode;
020    import org.xml.sax.SAXException;
021    
022    import javax.xml.XMLConstants;
023    import javax.xml.transform.stream.StreamSource;
024    import javax.xml.validation.Schema;
025    import javax.xml.validation.SchemaFactory;
026    import java.io.IOException;
027    import java.util.ArrayList;
028    import java.util.List;
029    
030    /**
031     * Service that loads Oozie workflow definition schema and registered extension schemas.
032     */
033    public class WorkflowSchemaService implements Service {
034    
035        public static final String CONF_PREFIX = Service.CONF_PREFIX + "WorkflowSchemaService.";
036    
037        public static final String CONF_EXT_SCHEMAS = CONF_PREFIX + "ext.schemas";
038    
039        private Schema dagSchema;
040    
041        private static final String OOZIE_WORKFLOW_XSD = "oozie-workflow-0.1.xsd";
042    
043        private Schema loadSchema(Configuration conf) throws SAXException, IOException {
044            List<StreamSource> sources = new ArrayList<StreamSource>();
045            sources.add(new StreamSource(IOUtils.getResourceAsStream(OOZIE_WORKFLOW_XSD, -1)));
046            String[] schemas = conf.getStrings(CONF_EXT_SCHEMAS);
047            if (schemas != null) {
048                for (String schema : schemas) {
049                    sources.add(new StreamSource(IOUtils.getResourceAsStream(schema, -1)));
050                }
051            }
052            SchemaFactory factory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
053            return factory.newSchema(sources.toArray(new StreamSource[sources.size()]));
054        }
055    
056        /**
057         * Initialize the service.
058         *
059         * @param services services instance.
060         * @throws ServiceException thrown if the service could not be initialized.
061         */
062        public void init(Services services) throws ServiceException {
063            try {
064                dagSchema = loadSchema(services.getConf());
065            }
066            catch (SAXException ex) {
067                throw new ServiceException(ErrorCode.E0130, ex.getMessage(), ex);
068            }
069            catch (IOException ex) {
070                throw new ServiceException(ErrorCode.E0131, ex.getMessage(), ex);
071            }
072        }
073    
074        /**
075         * Return the public interface of the service.
076         *
077         * @return {@link WorkflowSchemaService}.
078         */
079        public Class<? extends Service> getInterface() {
080            return WorkflowSchemaService.class;
081        }
082    
083        /**
084         * Destroy the service.
085         */
086        public void destroy() {
087            dagSchema = null;
088        }
089    
090        /**
091         * Return the schema for XML validation of application definitions.
092         *
093         * @return the schema for XML validation of application definitions.
094         */
095        public Schema getSchema() {
096            return dagSchema;
097        }
098    
099    }