    001    // Copyright 2010, 2011 The Apache Software Foundation
    002    //
    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.
    014
    015    package org.apache.tapestry5.internal.services.javascript;
    016
    017    import org.apache.tapestry5.Asset;
    018    import org.apache.tapestry5.SymbolConstants;
    019    import org.apache.tapestry5.func.F;
    020    import org.apache.tapestry5.func.Flow;
    021    import org.apache.tapestry5.internal.TapestryInternalUtils;
    022    import org.apache.tapestry5.ioc.annotations.Symbol;
    023    import org.apache.tapestry5.ioc.internal.util.CollectionFactory;
    024    import org.apache.tapestry5.ioc.services.SymbolSource;
    025    import org.apache.tapestry5.ioc.services.ThreadLocale;
    026    import org.apache.tapestry5.services.AssetSource;
    027    import org.apache.tapestry5.services.javascript.JavaScriptStack;
    028    import org.apache.tapestry5.services.javascript.StylesheetLink;
    029
    030    import java.util.Collections;
    031    import java.util.List;
    032    import java.util.Locale;
    033
    034    /**
    035     * JavaScriptStack for core components.
    036     *
    037     * @since 5.2.0
    038     */
    039    public class CoreJavaScriptStack implements JavaScriptStack {
    040      private final boolean productionMode;
    041
    042      private final SymbolSource symbolSource;
    043
    044      private final AssetSource assetSource;
    045
    046      private final ThreadLocale threadLocale;
    047
    048      private final List<Asset> javaScriptStack, stylesheetStack;
    049
    050      private static final String ROOT = "org/apache/tapestry5";
    051
    052      private static final String[] CORE_JAVASCRIPT = new String[]
    053              {
    054                      // Core scripts added to any page that uses scripting
    055
    056                      "${tapestry.underscore}",
    057
    058                      "${tapestry.scriptaculous}/prototype.js",
    059
    060                      "${tapestry.scriptaculous}/scriptaculous.js",
    061
    062                      "${tapestry.scriptaculous}/effects.js",
    063
    064                      // Below uses functions defined by the prior three.
    065
    066                      // Order is important, there are some dependencies
    067                      // going on here. Switching over to a more managed module system
    068                      // is starting to look like a really nice idea!
    069
    070                      ROOT + "/t5-core.js",
    071
    072                      ROOT + "/t5-spi.js",
    073
    074                      ROOT + "/t5-prototype.js",
    075
    076                      ROOT + "/t5-init.js",
    077
    078                      ROOT + "/t5-pubsub.js",
    079
    080                      ROOT + "/t5-events.js",
    081
    082                      ROOT + "/t5-dom.js",
    083
    084                      ROOT + "/t5-console.js",
    085
    086                      ROOT + "/t5-ajax.js",
    087
    088                      ROOT + "/t5-formfragment.js",
    089
    090                      ROOT + "/t5-alerts.js",
    091
    092                      ROOT + "/tapestry.js",
    093
    094                      ROOT + "/tapestry-console.js",
    095
    096                      ROOT + "/tree.js",
    097              };
    098
    099      // Because of changes to the logic of how stylesheets get incorporated, the default stylesheet
    100      // was removed, the logic for it is now in TapestryModule.contributeMarkupRenderer().
    101
    102      private static final String[] CORE_STYLESHEET = new String[]
    103              {
    104                      ROOT + "/tapestry-console.css",
    105
    106                      ROOT + "/t5-alerts.css",
    107
    108                      ROOT + "/tree.css"
    109              };
    110
    111      public CoreJavaScriptStack(
    112              @Symbol(SymbolConstants.PRODUCTION_MODE)
    113              boolean productionMode,
    114
    115              SymbolSource symbolSource,
    116
    117              AssetSource assetSource,
    118
    119              ThreadLocale threadLocale) {
    120        this.symbolSource = symbolSource;
    121        this.productionMode = productionMode;
    122        this.assetSource = assetSource;
    123        this.threadLocale = threadLocale;
    124
    125        javaScriptStack = convertToAssets(CORE_JAVASCRIPT);
    126        stylesheetStack = convertToAssets(CORE_STYLESHEET);
    127      }
    128
    129      public String getInitialization() {
    130        return productionMode ? null : "Tapestry.DEBUG_ENABLED = true;";
    131      }
    132
    133      public List<String> getStacks() {
    134        return Collections.emptyList();
    135      }
    136
    137      private List<Asset> convertToAssets(String[] paths) {
    138        List<Asset> assets = CollectionFactory.newList();
    139
    140        for (String path : paths) {
    141          assets.add(expand(path, null));
    142        }
    143
    144        return Collections.unmodifiableList(assets);
    145      }
    146
    147      private Asset expand(String path, Locale locale) {
    148        String expanded = symbolSource.expandSymbols(path);
    149
    150        return assetSource.getAsset(null, expanded, locale);
    151      }
    152
    153      public List<Asset> getJavaScriptLibraries() {
    154        Asset messages = assetSource.getAsset(null, ROOT + "/tapestry-messages.js", threadLocale.getLocale());
    155
    156        return createStack(javaScriptStack, messages).toList();
    157      }
    158
    159      public List<StylesheetLink> getStylesheets() {
    160        return createStack(stylesheetStack).map(TapestryInternalUtils.assetToStylesheetLink)
    161                .toList();
    162      }
    163
    164      private Flow<Asset> createStack(List<Asset> stack, Asset... assets) {
    165        return F.flow(stack).append(assets);
    166      }
    167    }