Package com.alibaba.citrus.service.resource.filter

Source Code of com.alibaba.citrus.service.resource.filter.XsltResourceFilter

/*
* Copyright 2010 Alibaba Group Holding Limited.
* All rights reserved.
*
* 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
*
* 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 com.alibaba.citrus.service.resource.filter;

import static com.alibaba.citrus.service.resource.ResourceLoadingService.*;
import static com.alibaba.citrus.util.Assert.*;
import static com.alibaba.citrus.util.StringUtil.*;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Set;

import javax.xml.transform.Result;
import javax.xml.transform.Source;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.stream.StreamResult;
import javax.xml.transform.stream.StreamSource;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.alibaba.citrus.service.resource.Resource;
import com.alibaba.citrus.service.resource.ResourceFilter;
import com.alibaba.citrus.service.resource.ResourceFilterChain;
import com.alibaba.citrus.service.resource.ResourceLoadingOption;
import com.alibaba.citrus.service.resource.ResourceLoadingService;
import com.alibaba.citrus.service.resource.ResourceMatchResult;
import com.alibaba.citrus.service.resource.ResourceNotFoundException;
import com.alibaba.citrus.service.resource.support.ByteArrayResource;
import com.alibaba.citrus.service.resource.support.FileResource;
import com.alibaba.citrus.util.StringUtil;
import com.alibaba.citrus.util.io.StreamUtil;

/**
* ��xml resource�任��ʽ��filter��
*
* @author Michael Zhou
*/
public class XsltResourceFilter implements ResourceFilter {
    private static final Logger log = LoggerFactory.getLogger(XsltResourceFilter.class);
    private ResourceLoadingService resourceLoadingService;
    private String xslt;
    private String saveTo;
    private File saveToDir;
    private boolean failIfNotFound = true;

    public void setXslt(String xslt) {
        this.xslt = trimToNull(xslt);
    }

    public void setFailIfNotFound(boolean failIfNotFound) {
        this.failIfNotFound = failIfNotFound;
    }

    public void setSaveTo(String saveTo) {
        this.saveTo = StringUtil.trimToNull(saveTo);
    }

    public void init(ResourceLoadingService resourceLoadingService) {
        this.resourceLoadingService = assertNotNull(resourceLoadingService, "resourceLoadingService");

        assertNotNull(xslt, "missing xslt");
    }

    private File getSaveToDir() {
        if (saveToDir != null) {
            return saveToDir;
        }

        if (saveTo == null) {
            return null;

        }

        File dir;

        try {
            dir = resourceLoadingService.getResourceAsFile(saveTo, FOR_CREATE);

            if (!dir.exists()) {
                dir.mkdirs();
            }
        } catch (ResourceNotFoundException e) {
            throw new IllegalArgumentException("Specified saveTo dir is not exist: " + saveTo, e);
        }

        if (!dir.exists()) {
            throw new IllegalArgumentException("Specified saveTo dir is not exist: " + saveTo);
        }

        saveToDir = dir;

        log.debug("Transformed resource will be saved into directory: {}", dir.getAbsolutePath());

        return saveToDir;
    }

    public Resource doFilter(ResourceMatchResult filterMatchResult, Set<ResourceLoadingOption> options,
                             ResourceFilterChain chain) throws ResourceNotFoundException {
        String resourceName = filterMatchResult.getResourceName();
        String xsltName = filterMatchResult.substitute(xslt);
        Resource xsltRes;

        try {
            xsltRes = resourceLoadingService.getResource(xsltName);
        } catch (ResourceNotFoundException e) {
            xsltRes = null;
        }

        if (xsltRes == null && failIfNotFound) {
            throw new ResourceNotFoundException("Could not find XSLT file for " + this + ", resourceName="
                    + filterMatchResult.getResourceName());
        }

        Resource resource = chain.doFilter(filterMatchResult, options);

        resource = transformDocument(resource, resourceName, xsltRes, xsltName);

        if (getSaveToDir() != null) {
            resource = saveToDir(resource, resourceName);
        }

        return resource;
    }

    /**
     * ��XSLTת��XML��Դ��
     */
    private Resource transformDocument(Resource xmlRes, String xmlResName, Resource xsltRes, String xsltResName)
            throws ResourceNotFoundException {
        log.debug("Applying XSLT \"{}\" to resource \"{}\"", xsltResName, xmlResName);

        try {
            TransformerFactory factory = TransformerFactory.newInstance();
            Source xsltSource = new StreamSource(xsltRes.getInputStream(), xsltResName);
            Transformer transformer = factory.newTransformer(xsltSource);

            Source source = new StreamSource(xmlRes.getInputStream(), xmlResName);
            ByteArrayOutputStream baos = new ByteArrayOutputStream();
            Result result = new StreamResult(baos);

            transformer.transform(source, result);

            return new ByteArrayResource(baos.toByteArray());
        } catch (Exception e) {
            throw new ResourceNotFoundException("Could not apply XSLT \"" + xsltResName + "\" to resource \""
                    + xmlResName + "\"", e);
        }
    }

    /**
     * ����Դ���浽Ŀ¼�С�
     */
    private Resource saveToDir(Resource resource, String resourceName) {
        File fileToSave = new File(saveToDir, resourceName);
        File parentDir = fileToSave.getParentFile();

        if (!parentDir.exists()) {
            parentDir.mkdirs();
        }

        if (!parentDir.exists()) {
            log.warn("Directory to save is not exist: " + parentDir.getAbsolutePath());
            return resource;
        }

        FileOutputStream fos = null;

        try {
            fos = new FileOutputStream(fileToSave);
            StreamUtil.io(resource.getInputStream(), fos, true, true);
        } catch (IOException e) {
            log.warn("Could not save to file: " + fileToSave.getAbsolutePath(), e);
            return resource;
        }

        Resource transformed = new FileResource(fileToSave);

        if (log.isDebugEnabled()) {
            log.debug("Transformed resource is saved to " + fileToSave.getAbsolutePath());
        }

        return transformed;
    }

    @Override
    public String toString() {
        return getClass().getSimpleName() + "[" + xslt + "]";
    }
}
TOP

Related Classes of com.alibaba.citrus.service.resource.filter.XsltResourceFilter

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.