Package com.granule.utils

Source Code of com.granule.utils.CSSHandler$ReplaceInfo

/*
* Copyright 2010 Granule Inc.
*
* 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.granule.utils;

/**
* User: Dario Wunsch
* Date: 14.07.2010
* Time: 22:08:04
*/

import com.granule.CompressorSettings;
import com.granule.ExternalFragment;
import com.granule.FragmentDescriptor;
import com.granule.IRequestProxy;
import com.granule.JSCompileException;
import com.granule.logging.Logger;
import com.granule.logging.LoggerFactory;

import java.io.File;
import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public final class CSSHandler {
    private static final String stringLiteralRegex = "(\"(?:\\.|[^\\\"])*\"|'(?:\\.|[^\\'])*')";
    private static final String urlRegex = String.format(
            "(?:url\\(\\s*(%s|[^)]*)\\s*\\))", stringLiteralRegex);
    private static final String importRegex = String.format(
            "(?:@import\\s+(%s|%s))", urlRegex, stringLiteralRegex);

    private static final Pattern regex = Pattern.compile(String.format(
            "(%s)|(%s)|%s", importRegex, urlRegex, stringLiteralRegex));

    private class ReplaceInfo {
        boolean isImport = false;
        int begin;
        int end;
        String text;
    }


    public void parse(String line, List<ReplaceInfo> replaces, int start) {
        Matcher m = regex.matcher(line);

        while (m.find()) {
            try {
                if (m.group(3) != null) {
                    ReplaceInfo replace = new ReplaceInfo();
                    replace.isImport = true;
                    replace.text = cleanQuotesFromMatchString(m.group(3));
                    replace.begin = line.substring(0, m.start(3)).lastIndexOf("@import") + start;
                    replace.end = line.substring(m.end(3)).indexOf(";") + m.end(3) + 1 + start;
                    replaces.add(replace);
                }
                if (m.group(5) != null) {
                    ReplaceInfo replace = new ReplaceInfo();
                    replace.isImport = true;
                    replace.text = cleanQuotesFromMatchString(m.group(5));
                    replace.begin = line.substring(0, m.start(5)).lastIndexOf("@import") + start;
                    replace.end = line.substring(m.end(5)).indexOf(";") + m.end(5) + 1 + start;
                    replaces.add(replace);
                }
                if (m.group(7) != null) {
                    ReplaceInfo replace = new ReplaceInfo();
                    replace.text = cleanQuotesFromMatchString(m.group(7));
                    replace.begin = m.start(7) + start;
                    replace.end = m.end(7) + start;
                    if (!PathUtils.isWebAddress(replace.text))
                        replaces.add(replace);
                }
            } catch (IndexOutOfBoundsException e) { /* eat move on */ }
        }
    }

    private String cleanQuotesFromMatchString(String match) {
        if (match.charAt(0) == '\'' || match.charAt(0) == '"')
            return match.substring(1, match.length() - 1);
        return match;
    }

    public String handle(FragmentDescriptor fd, IRequestProxy request, CompressorSettings settings,
                         List<FragmentDescriptor> deps) throws JSCompileException {
        try {
            if (fd instanceof ExternalFragment && settings.isIgnoreMissedFiles() &&
                    !(new File(request.getRealPath(((ExternalFragment) fd).getFilePath()))).exists()) {
                logger.warn(MessageFormat.format("File {0} not found, ignored", ((ExternalFragment) fd).getFilePath()));
                return "";
            }
            String css = fd.getContentText(request);
            String newPath = (fd instanceof ExternalFragment) ? ((ExternalFragment) fd).getFolderPath() : "";
            final List<ReplaceInfo> replaces = new ArrayList<ReplaceInfo>();
            String[] lines = css.split("\n");
            int startLine = 0;
            for (String line : lines) {
                parse(line, replaces, startLine);
                startLine += line.length() + 1;
            }
            if (replaces.size() == 0)
                return css;
            else {
                int start = 0;
                StringBuilder sb = new StringBuilder();
                for (ReplaceInfo replaceInfo : replaces) {
                    sb.append(css.substring(start, replaceInfo.begin));
                    if (!replaceInfo.isImport)
                        sb.append(PathUtils.clean(newPath + replaceInfo.text));
                    else {
                        boolean cyclicLink = false;
                        String cssPath = PathUtils.clean(((newPath.length() > 0 && newPath.charAt(0) != '/') ? "/" :
                                "") + newPath + replaceInfo.text);
                        for (FragmentDescriptor dep : deps)
                            if (dep instanceof ExternalFragment) {
                                ExternalFragment ef = (ExternalFragment) dep;
                                if (ef.getFilePath() != null && ef.getFilePath().equals(cssPath)) {
                                    cyclicLink = true;
                                    break;
                                }
                            }
                        if (cyclicLink) {
                            logger.error("Found cyclic link!!!!");
                            start = replaceInfo.end;
                            continue;
                        }
                        boolean addFile = true;
                        if (settings.isIgnoreMissedFiles() && !(new File(request.getRealPath(cssPath))).exists()) {
                            logger.warn(MessageFormat.format("File {0} not found, ignored", cssPath));
                            addFile = false;
                        }
                        if (addFile) {
                            String filename;
                            if (replaceInfo.text.startsWith("/"))
                                filename = replaceInfo.text;
                            else filename = cssPath;
                            FragmentDescriptor imp = new ExternalFragment(filename);
                            deps.add(imp);
                            sb.append(handle(imp, request, settings, deps));
                        }
                    }
                    start = replaceInfo.end;
                }
                sb.append(css.substring(start));
                return sb.toString();
            }
        } catch (Exception e) {
            throw new JSCompileException(e);
        }
    }

    private static final Logger logger = LoggerFactory.getLogger(CSSHandler.class);
}
TOP

Related Classes of com.granule.utils.CSSHandler$ReplaceInfo

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.