Package com.google.code.jqwicket

Source Code of com.google.code.jqwicket.JQContributionRenderer

/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements.  See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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.google.code.jqwicket;

import com.google.code.jqwicket.api.IJQStatement;
import com.google.code.jqwicket.api.JQuery;
import org.apache.wicket.Application;
import org.apache.wicket.Component;
import org.apache.wicket.MetaDataKey;
import org.apache.wicket.behavior.Behavior;
import org.apache.wicket.javascript.IJavaScriptCompressor;
import org.apache.wicket.markup.head.CssHeaderItem;
import org.apache.wicket.markup.head.IHeaderResponse;
import org.apache.wicket.markup.head.JavaScriptHeaderItem;
import org.apache.wicket.markup.head.OnDomReadyHeaderItem;
import org.apache.wicket.request.cycle.RequestCycle;
import org.apache.wicket.request.resource.CssResourceReference;
import org.apache.wicket.request.resource.JavaScriptResourceReference;

import java.util.*;

import static com.google.code.jqwicket.Utils.isEmpty;

/**
* Wicket's behavior implementation able to render all necessary jquery/css resources gathered from the component
* hierarchy to the html-page head section.
*
* @author mkalina
*/
public class JQContributionRenderer extends Behavior {

    private static final long serialVersionUID = 1L;

    private static final MetaDataKey<JQContributionRenderer> KEY = new MetaDataKey<JQContributionRenderer>() {
        private static final long serialVersionUID = 1L;
    };

    public static JQContributionRenderer get() {
        JQContributionRenderer target = RequestCycle.get().getMetaData(KEY);
        if (target == null) {
            target = new JQContributionRenderer();
            RequestCycle.get().setMetaData(KEY, target);
        }
        return target;
    }

    private Set<IJQHeaderContributor> contributors;

    JQContributionRenderer() {
    }


    public JQContributionRenderer addContributors(Collection<? extends IJQHeaderContributor> contributors) {

        if (this.contributors == null)
            this.contributors = new LinkedHashSet<IJQHeaderContributor>();

        if (Utils.isNotEmpty(contributors))
            this.contributors.addAll(contributors);

        return this;
    }

    public JQContributionRenderer addContributor(IJQHeaderContributor contributor) {

        if (this.contributors == null)
            this.contributors = new LinkedHashSet<IJQHeaderContributor>();

        this.contributors.add(contributor);
        return this;
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public void renderHead(Component component, IHeaderResponse response) {

        if (isEmpty(this.contributors))
            return;

        JQContributionConfig config = JQContributionConfig.get();
        JQHeaderContributionTarget target = new JQHeaderContributionTarget();
        for (IJQHeaderContributor c : this.contributors) {
            c.contribute(target);
        }

        if (!target.hasResourcesToRender())
            return;

        // 1. render global javascripts
        this.renderJavaScriptOutsideDocumentReady(response, target.getJQStatementsOutsideDocumentReady());

        // 2. render resources from global config
        response.render(JavaScriptHeaderItem.forReference(Application.get()
                .getJavaScriptLibrarySettings()
                .getJQueryReference()));

        renderJsResources(response,
                Arrays.asList(config.getJqueryUiJsUrl()), Arrays.asList(config.getJqueryUiJsResourceReference()));
        renderCssResources(response,
                Arrays.asList(config.getJqueryUiCssUrl()), Arrays.asList(config.getJqueryUiCssResourceReference()));


        // 3. render resource explicitly added to the target
        this.renderJsResources(response, target.getJsResourceUrls(), target.getJsResourceReferences());
        this.renderCssResources(response, target.getCssResourceUrls(), target.getCssResourceReferences());

        // 4. render "documentReady"-script
        this.renderJavaScriptInsideDocumentReady(response, target.getJQStatementsInsideDocumentReady());

        // clear contributors after rendering
        this.contributors.clear();
    }

    private void renderJsResources(IHeaderResponse response, Collection<CharSequence> urls,
                                   Collection<JavaScriptResourceReference> refs) {
        JQContributionConfig config = JQContributionConfig.get();
        if (config.isRenderJavascriptResourceRefsBeforeUrls()) {
            this.renderJsResourcesRefs(response, refs);
            this.renderJsResourcesUrls(response, urls);
        } else {
            this.renderJsResourcesUrls(response, urls);
            this.renderJsResourcesRefs(response, refs);
        }
    }

    private void renderCssResources(IHeaderResponse response, Collection<CharSequence> urls,
                                    Collection<CssResourceReference> refs) {
        JQContributionConfig config = JQContributionConfig.get();
        if (config.isRenderCssResourceRefsBeforeUrls()) {
            this.renderCssResourcesRefs(response, refs);
            this.renderCssResourcesUrls(response, urls);
        } else {
            this.renderCssResourcesUrls(response, urls);
            this.renderCssResourcesRefs(response, refs);
        }
    }


    private void renderJsResourcesUrls(IHeaderResponse response, Collection<CharSequence> resources) {
        for (CharSequence url : resources) {
            response.render(JavaScriptHeaderItem.forUrl(determineResourcesUrl(url)));
        }
    }

    private void renderJsResourcesRefs(IHeaderResponse response, Collection<JavaScriptResourceReference> resources) {
        for (JavaScriptResourceReference ref : resources) {
            if (ref != null)
                response.render(JavaScriptHeaderItem.forReference(ref));
        }
    }

    private void renderCssResourcesUrls(IHeaderResponse response, Collection<CharSequence> resources) {
        for (CharSequence url : resources) {
            response.render(CssHeaderItem.forUrl(determineResourcesUrl(url)));
        }
    }


    private void renderCssResourcesRefs(IHeaderResponse response, Collection<CssResourceReference> resources) {
        for (CssResourceReference ref : resources) {
            if (ref != null)
                response.render(CssHeaderItem.forReference(ref));
        }
    }


    private String determineResourcesUrl(CharSequence url) {
        if (Utils.isBlank(url))
            throw new IllegalArgumentException("url cannot be empty or null");

        String urlString = String.valueOf(url);
        if (urlString.toLowerCase().startsWith("http://") || urlString.toLowerCase().startsWith("https://"))
            return urlString;

        RequestCycle rc = RequestCycle.get();
        return rc.getUrlRenderer().renderContextRelativeUrl(urlString);
    }


    private void renderJavaScriptOutsideDocumentReady(IHeaderResponse response, Collection<IJQStatement> statements) {

        if (isEmpty(statements))
            return;

        StringBuffer buf = new StringBuffer();
        for (IJQStatement s : statements) {
            buf.append(s);
        }
        response.render(JavaScriptHeaderItem.forScript(compressJavaScript(buf), UUID.randomUUID().toString()));
    }

    private void renderJavaScriptInsideDocumentReady(IHeaderResponse response, Collection<IJQStatement> statements) {

        if (isEmpty(statements))
            return;

        JQContributionConfig config = JQContributionConfig.get();

        StringBuffer script = new StringBuffer();
        if (Utils.isNotBlank(config.getNonConflictAlias())) {
            script.append("var ").append(config.getNonConflictAlias())
                    .append(" = jQuery.noConflict();\n");
        }

        script.append(compressJavaScript(JQuery.documentReady(statements)));

        if (Utils.isNotBlank(script))
            response.render(OnDomReadyHeaderItem.forScript(script.toString()));
    }

    private CharSequence compressJavaScript(CharSequence script) {

        final IJavaScriptCompressor compressor;

        if (JQContributionConfig.get().isUseYuiJavascriptCompressor())
            compressor = YuiJavascriptCompressor.get();
        else
            compressor = Application.get().getResourceSettings().getJavaScriptCompressor();

        return (compressor != null && Utils.isNotBlank(script)) ?
                compressor.compress(String.valueOf(script)) : script;
    }
}
TOP

Related Classes of com.google.code.jqwicket.JQContributionRenderer

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.