001/*
002 * This library is part of OpenCms -
003 * the Open Source Content Management System
004 *
005 * Copyright (c) Alkacon Software GmbH & Co. KG (http://www.alkacon.com)
006 *
007 * This library is free software; you can redistribute it and/or
008 * modify it under the terms of the GNU Lesser General Public
009 * License as published by the Free Software Foundation; either
010 * version 2.1 of the License, or (at your option) any later version.
011 *
012 * This library is distributed in the hope that it will be useful,
013 * but WITHOUT ANY WARRANTY; without even the implied warranty of
014 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
015 * Lesser General Public License for more details.
016 *
017 * For further information about Alkacon Software GmbH & Co. KG, please see the
018 * company website: http://www.alkacon.com
019 *
020 * For further information about OpenCms, please see the
021 * project website: http://www.opencms.org
022 *
023 * You should have received a copy of the GNU Lesser General Public
024 * License along with this library; if not, write to the Free Software
025 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
026 */
027
028package org.opencms.setup.comptest;
029
030import com.alkacon.simapi.RenderSettings;
031import com.alkacon.simapi.Simapi;
032
033import org.opencms.loader.CmsImageScaler;
034import org.opencms.setup.CmsSetupBean;
035
036import java.awt.image.BufferedImage;
037import java.io.ByteArrayOutputStream;
038import java.io.File;
039import java.io.FileInputStream;
040import java.io.FileOutputStream;
041import java.io.IOException;
042import java.util.Arrays;
043import java.util.Iterator;
044
045import javax.imageio.ImageIO;
046import javax.imageio.ImageReader;
047import javax.imageio.ImageWriter;
048
049/**
050 * Tests the image processing capabilities.<p>
051 *
052 * @since 6.1.8
053 */
054public class CmsSetupTestSimapi implements I_CmsSetupTest {
055
056    /** The test name. */
057    public static final String TEST_NAME = "Image Processing";
058
059    /**
060     * @see org.opencms.setup.comptest.I_CmsSetupTest#execute(org.opencms.setup.CmsSetupBean)
061     */
062    public CmsSetupTestResult execute(CmsSetupBean setupBean) {
063
064        CmsSetupTestResult testResult = new CmsSetupTestResult(this);
065        boolean ok = true;
066        Throwable ex = null;
067        try {
068            RenderSettings settings = new RenderSettings(Simapi.RENDER_QUALITY);
069            settings.setCompressionQuality(0.85f);
070            Simapi simapi = new Simapi(settings);
071
072            ImageIO.scanForPlugins();
073            Iterator<ImageReader> pngReaders = ImageIO.getImageReadersByFormatName(Simapi.TYPE_PNG);
074            if (!pngReaders.hasNext()) {
075                throw (new Exception("No Java ImageIO readers for the PNG format are available."));
076            }
077            Iterator<ImageWriter> pngWriters = ImageIO.getImageWritersByFormatName(Simapi.TYPE_PNG);
078            if (!pngWriters.hasNext()) {
079                throw (new Exception("No Java ImageIO writers for the PNG format are available."));
080            }
081
082            String basePath = setupBean.getWebAppRfsPath();
083            if (!basePath.endsWith(File.separator)) {
084                basePath += File.separator;
085            }
086            basePath += CmsSetupBean.FOLDER_SETUP + "resources" + File.separator;
087
088            CmsImageScaler scaler = new CmsImageScaler();
089            byte[] scaled;
090            BufferedImage result;
091
092            BufferedImage source = Simapi.read(basePath + "test1.png");
093            String targetName = basePath + "test3.png";
094            scaler.parseParameters("w:50,h:18");
095            scaled = scaler.scaleImage(simapi.getBytes(source, Simapi.TYPE_PNG), targetName);
096            writeFile(targetName, scaled);
097            result = Simapi.read(targetName);
098
099            BufferedImage expected = Simapi.read(basePath + "test2.png");
100
101            ok = Arrays.equals(simapi.getBytes(expected, Simapi.TYPE_PNG), simapi.getBytes(result, Simapi.TYPE_PNG));
102        } catch (Throwable e) {
103            ok = false;
104            ex = e;
105        }
106
107        if (ok) {
108            testResult.setResult(RESULT_PASSED);
109            testResult.setGreen();
110        } else {
111            testResult.setYellow();
112            if (ex != null) {
113                testResult.setResult(RESULT_FAILED);
114                testResult.setHelp(ex.toString());
115                testResult.setInfo(
116                    "<p><code>-Djava.awt.headless=true</code> JVM parameter or X-Server may be missing.<br>"
117                        + "<b>You can continue the setup, but image processing will be disabled.</b></p>");
118            } else {
119                testResult.setResult(RESULT_WARNING);
120                testResult.setHelp("Image processing works but result does not exactly match.");
121                StringBuffer info = new StringBuffer();
122                info.append("<p>Please check the following images for visible differences:</p>");
123                info.append("<table width='100%'>");
124                info.append("<tr><th>Expected</th><th>Result</th></tr>");
125                info.append("<tr><td align='center' width='50%'><img src='resources/test2.png'></td>");
126                info.append("<td align='center' width='50%'><img src='resources/test3.png'></td></table>");
127                info.append(
128                    "<p><b>You can continue the setup, but image processing may not always work as expected.</b></p>");
129                testResult.setInfo(info.toString());
130            }
131        }
132        return testResult;
133    }
134
135    /**
136     * @see org.opencms.setup.comptest.I_CmsSetupTest#getName()
137     */
138    public String getName() {
139
140        return TEST_NAME;
141    }
142
143    private byte[] readFile(File file) throws IOException {
144
145        // create input and output stream
146        FileInputStream in = new FileInputStream(file);
147        ByteArrayOutputStream out = new ByteArrayOutputStream();
148
149        // read the file content
150        int c;
151        while ((c = in.read()) != -1) {
152            out.write(c);
153        }
154
155        in.close();
156        out.close();
157
158        return out.toByteArray();
159    }
160
161    private File writeFile(String rfsName, byte[] content) throws IOException {
162
163        File f = new File(rfsName);
164        File p = f.getParentFile();
165        if (!p.exists()) {
166            // create parent folders
167            p.mkdirs();
168        }
169        // write file contents
170        FileOutputStream fs = new FileOutputStream(f);
171        fs.write(content);
172        fs.close();
173        return f;
174    }
175}