Package org.bladerunnerjs.plugin.plugins.bundlers.commonjs

Source Code of org.bladerunnerjs.plugin.plugins.bundlers.commonjs.CommonJsSourceModule$ComputedValue

package org.bladerunnerjs.plugin.plugins.bundlers.commonjs;

import java.io.File;
import java.io.IOException;
import java.io.Reader;
import java.io.StringReader;
import java.io.StringWriter;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.apache.commons.io.IOUtils;
import org.bladerunnerjs.memoization.Getter;
import org.bladerunnerjs.memoization.MemoizedValue;
import org.bladerunnerjs.model.Asset;
import org.bladerunnerjs.model.AssetFileInstantationException;
import org.bladerunnerjs.model.AssetLocation;
import org.bladerunnerjs.model.AssetLocationUtility;
import org.bladerunnerjs.model.AugmentedContentSourceModule;
import org.bladerunnerjs.model.BladerunnerConf;
import org.bladerunnerjs.model.BundlableNode;
import org.bladerunnerjs.model.SourceModulePatch;
import org.bladerunnerjs.model.exception.AmbiguousRequirePathException;
import org.bladerunnerjs.model.exception.ConfigException;
import org.bladerunnerjs.model.exception.ModelOperationException;
import org.bladerunnerjs.model.exception.RequirePathException;
import org.bladerunnerjs.model.exception.UnresolvableRequirePathException;
import org.bladerunnerjs.utility.PrimaryRequirePathUtility;
import org.bladerunnerjs.utility.RelativePathUtility;
import org.bladerunnerjs.utility.UnicodeReader;

import com.Ostermiller.util.ConcatReader;

public class CommonJsSourceModule implements AugmentedContentSourceModule {

  public static final String COMMONJS_DEFINE_BLOCK_HEADER = "define('%s', function(require, exports, module) {\n";
  public static final String COMMONJS_DEFINE_BLOCK_FOOTER = "\n});\n";

  private static final Pattern matcherPattern = Pattern.compile("(require|br\\.Core\\.alias|caplin\\.alias|getAlias|getService)\\([ ]*[\"']([^)]+)[\"'][ ]*\\)");
 
  private File assetFile;
  private AssetLocation assetLocation;
 
  private SourceModulePatch patch;
 
  private MemoizedValue<ComputedValue> computedValue;
  private List<String> requirePaths = new ArrayList<>();
  public static final String JS_STYLE = "common-js";
 
  public CommonJsSourceModule(File assetFile, AssetLocation assetLocation) throws AssetFileInstantationException {
    this.assetLocation = assetLocation;
    this.assetFile = assetFile;
   
    String requirePath = assetLocation.requirePrefix() + "/" + RelativePathUtility.get(assetLocation.root().getFileInfoAccessor(), assetLocation.dir(), assetFile).replaceAll("\\.js$", "");
    requirePaths.add(requirePath);
   
    patch = SourceModulePatch.getPatchForRequirePath(assetLocation, getPrimaryRequirePath());
    computedValue = new MemoizedValue<>(getAssetPath()+" - computedValue", assetLocation.root(), assetFile, patch.getPatchFile(), BladerunnerConf.getConfigFilePath(assetLocation.root()));
  }
 
  @Override
  public List<Asset> getDependentAssets(BundlableNode bundlableNode) throws ModelOperationException {
    List<Asset> dependendAssets = new ArrayList<>();
    dependendAssets.addAll( getPreExportDefineTimeDependentAssets(bundlableNode) );
    dependendAssets.addAll( getPostExportDefineTimeDependentAssets(bundlableNode) );
    dependendAssets.addAll( getUseTimeDependentAssets(bundlableNode) );
    return dependendAssets;
  }
 
  @Override
  public List<String> getRequirePaths() {
    return requirePaths;
  }
 
 
  @Override
  public List<String> getAliasNames() throws ModelOperationException {
    return getComputedValue().aliases;
  }
 
  @Override
  public Reader getUnalteredContentReader() throws IOException {
    try
    {
      String defaultFileCharacterEncoding = assetLocation.root().bladerunnerConf().getDefaultFileCharacterEncoding();
      Reader assetReader = new UnicodeReader(assetFile, defaultFileCharacterEncoding);
      if (patch.patchAvailable()){
        return new ConcatReader( new Reader[] { assetReader, patch.getReader() });
      } else {
        return assetReader;
      }
    }
    catch (ConfigException ex)
    {
      throw new RuntimeException(ex);
    }
  }
 
  @Override
  public Reader getReader() throws IOException {
    return new ConcatReader(new Reader[] {
      new StringReader( String.format(COMMONJS_DEFINE_BLOCK_HEADER, getPrimaryRequirePath()) ),
      getUnalteredContentReader(),
      new StringReader( COMMONJS_DEFINE_BLOCK_FOOTER )
    });
  }
 
  @Override
  public String getPrimaryRequirePath() {
    return PrimaryRequirePathUtility.getPrimaryRequirePath(this);
  }
 
  @Override
  public boolean isEncapsulatedModule() {
    return true;
  }
 
  @Override
  public boolean isGlobalisedModule() {
    return false;
  }
 
  @Override
  public List<Asset> getPreExportDefineTimeDependentAssets(BundlableNode bundlableNode) throws ModelOperationException {
    return getSourceModulesForRequirePaths( bundlableNode, getComputedValue().preExportDefineTimeRequirePaths );
  }
 
  @Override
  public List<Asset> getPostExportDefineTimeDependentAssets(BundlableNode bundlableNode) throws ModelOperationException {
    return getSourceModulesForRequirePaths( bundlableNode, getComputedValue().postExportDefineTimeRequirePaths );
  }
 
  @Override
  public List<Asset> getUseTimeDependentAssets(BundlableNode bundlableNode) throws ModelOperationException {
    return getSourceModulesForRequirePaths( bundlableNode, getComputedValue().useTimeRequirePaths );
  }
 
  @Override
  public File dir() {
    return assetFile.getParentFile();
  }
 
  @Override
  public String getAssetName() {
    return assetFile.getName();
  }
 
  @Override
  public String getAssetPath() {
    return RelativePathUtility.get(assetLocation.root().getFileInfoAccessor(), assetLocation.assetContainer().app().dir(), assetFile);
  }
 
  @Override
  public AssetLocation assetLocation()
  {
    return assetLocation;
  }
 
  @Override
  public List<AssetLocation> assetLocations() {
    return AssetLocationUtility.getAllDependentAssetLocations(assetLocation);
  }
 
  private ComputedValue getComputedValue() throws ModelOperationException {
    CommonJsSourceModule sourceModule = this;
    return computedValue.value(new Getter<ModelOperationException>() {
      @Override
      public Object get() throws ModelOperationException {
        ComputedValue computedValue = new ComputedValue();
       
        try {
          try(Reader reader = new CommonJsPreExportDefineTimeDependenciesReader(sourceModule))
          {
            addRequirePathsFromReader(reader, computedValue.preExportDefineTimeRequirePaths, computedValue.aliases);
          }
         
          try(Reader reader = new CommonJsPostExportDefineTimeDependenciesReader(sourceModule))
          {
            addRequirePathsFromReader(reader, computedValue.postExportDefineTimeRequirePaths, computedValue.aliases);
          }

          try(Reader reader = new CommonJsUseTimeDependenciesReader(sourceModule))
          {
            addRequirePathsFromReader(reader, computedValue.useTimeRequirePaths, computedValue.aliases);
          }
        }
        catch(IOException e) {
          throw new ModelOperationException(e);
        }
       
        return computedValue;
      }
    });
  }
 
  private void addRequirePathsFromReader(Reader reader, Set<String> dependencies, List<String> aliases) throws IOException {
    StringWriter stringWriter = new StringWriter();
    IOUtils.copy(reader, stringWriter);
   
    Matcher m = matcherPattern.matcher(stringWriter.toString());
    while (m.find()) {
      String methodArgument = m.group(2);
     
      if (m.group(1).startsWith("require")) {
        String requirePath = methodArgument;
        dependencies.add(requirePath);
      }
      else if (m.group(1).startsWith("getService")){
        String serviceAliasName = methodArgument;
        //TODO: this is a big hack, remove the "SERVICE!" part and the same in BundleSetBuilder
        aliases.add("SERVICE!"+serviceAliasName);
      }
      else {
        aliases.add(methodArgument);
      }
    }
  }

  private List<Asset> getSourceModulesForRequirePaths(BundlableNode bundlableNode, Set<String> requirePaths) throws ModelOperationException {
    try {
      return bundlableNode.getLinkedAssets( assetLocation, new ArrayList<>(requirePaths) );
    }
    catch (AmbiguousRequirePathException | UnresolvableRequirePathException e) {
            e.setSourceRequirePath(getPrimaryRequirePath());
            throw new ModelOperationException(e);
        }
        catch (RequirePathException e) {
            throw new ModelOperationException(e);
        }
  }
 
  private class ComputedValue {
    public Set<String> preExportDefineTimeRequirePaths = new HashSet<>();
    public Set<String> postExportDefineTimeRequirePaths = new HashSet<>();
    public Set<String> useTimeRequirePaths = new HashSet<>();
    public List<String> aliases = new ArrayList<>();
  }
 
}
TOP

Related Classes of org.bladerunnerjs.plugin.plugins.bundlers.commonjs.CommonJsSourceModule$ComputedValue

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.