de.swm.gwt.linker.PermutationMapLinker Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of swm-gwt-client Show documentation
Show all versions of swm-gwt-client Show documentation
Plain GWT Swm erweiterungen, auch zur benutzung in mobilen Geraeten
The newest version!
package de.swm.gwt.linker;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import java.util.SortedSet;
import java.util.TreeMap;
import com.google.gwt.core.ext.LinkerContext;
import com.google.gwt.core.ext.TreeLogger;
import com.google.gwt.core.ext.TreeLogger.Type;
import com.google.gwt.core.ext.UnableToCompleteException;
import com.google.gwt.core.ext.linker.AbstractLinker;
import com.google.gwt.core.ext.linker.ArtifactSet;
import com.google.gwt.core.ext.linker.ConfigurationProperty;
import com.google.gwt.core.ext.linker.EmittedArtifact;
import com.google.gwt.core.ext.linker.LinkerOrder;
import com.google.gwt.core.ext.linker.Shardable;
import com.google.gwt.core.ext.linker.SyntheticArtifact;
import com.google.gwt.core.ext.linker.impl.SelectionInformation;
import de.swm.gwt.linker.server.BindingProperty;
/**
* @author Daniel Kurka (see http://code.google.com/p/mgwt/)
*
*
* Modified by Guido Wimmel (SWM Services GmbH):
* consistently use "/" as path separators in generated file
*/
@LinkerOrder(LinkerOrder.Order.POST)
@Shardable
public class PermutationMapLinker extends AbstractLinker {
public static final String EXTERNAL_FILES_CONFIGURATION_PROPERTY_NAME = "html5manifestlinker_files";
public static final String PERMUTATION_MANIFEST_FILE_ENDING = ".manifest";
public static final String PERMUTATION_FILE_ENDING = ".perm.xml";
public static final String MANIFEST_MAP_FILE_NAME = "manifest.map";
private XMLPermutationProvider xmlPermutationProvider;
public PermutationMapLinker() {
xmlPermutationProvider = new XMLPermutationProvider();
manifestWriter = new ManifestWriter();
}
private ManifestWriter manifestWriter;
@Override
public String getDescription() {
return "PermutationMapLinker";
}
@Override
public ArtifactSet link(TreeLogger logger, LinkerContext context, ArtifactSet artifacts, boolean onePermutation)
throws UnableToCompleteException {
if (onePermutation) {
Map> permutationMap = buildPermutationMap(logger, context, artifacts);
Set>> entrySet = permutationMap.entrySet();
// since we are in onePermutation there should be just one
// strongName
// better make sure..
if (permutationMap.size() != 1) {
logger.log(Type.ERROR, "There should be only one permutation right now, but there were: '"
+ permutationMap.size() + "'");
throw new UnableToCompleteException();
}
Entry> next = entrySet.iterator().next();
String strongName = next.getKey();
Set bindingProperties = next.getValue();
logger.log(Type.INFO, "Linker call for specific permutation with strong name " + strongName
+ " and binding properties " + bindingProperties);
// all artifacts for this compilation
Set artifactsForCompilation = getArtifactsForCompilation(logger, context, artifacts);
ArtifactSet toReturn = new ArtifactSet(artifacts);
PermutationArtifact permutationArtifact = new PermutationArtifact(PermutationMapLinker.class, strongName,
artifactsForCompilation, bindingProperties);
toReturn.add(permutationArtifact);
return toReturn;
}
ArtifactSet toReturn = new ArtifactSet(artifacts);
Map> map = buildPermutationMap(logger, context, artifacts);
if (map.size() == 0) {
// hosted mode
return toReturn;
}
logger.log(Type.INFO, "Final linker call with binding properties map " + map);
Map permutationArtifactAsMap = getPermutationArtifactAsMap(artifacts);
Set externalFiles = getExternalFiles(logger, context);
Set allPermutationFiles = getAllPermutationFiles(permutationArtifactAsMap);
// get all artifacts
Set allArtifacts = getArtifactsForCompilation(logger, context, artifacts);
for (Entry entry : permutationArtifactAsMap.entrySet()) {
PermutationArtifact permutationArtifact = entry.getValue();
// make a copy of all artifacts
HashSet filesForCurrentPermutation = new HashSet(allArtifacts);
// remove all permutations
filesForCurrentPermutation.removeAll(allPermutationFiles);
// add files of the one permutation we are interested in
// leaving the common stuff for all permutations in...
filesForCurrentPermutation.addAll(entry.getValue().getPermutationFiles());
String permXml = buildPermXml(logger, permutationArtifact, filesForCurrentPermutation, externalFiles);
// emit permutation information file
SyntheticArtifact emitString = emitString(logger, permXml, permutationArtifact.getPermutationName()
+ PERMUTATION_FILE_ENDING);
toReturn.add(emitString);
// build manifest
String maniFest = buildManiFest(entry.getKey(), filesForCurrentPermutation, externalFiles);
toReturn.add(emitString(logger, maniFest, entry.getKey() + PERMUTATION_MANIFEST_FILE_ENDING));
}
toReturn.add(createPermutationMap(logger, map));
return toReturn;
}
protected String buildPermXml(TreeLogger logger, PermutationArtifact permutationArtifact,
Set gwtCompiledFiles, Set otherResources) throws UnableToCompleteException {
HashSet namesForPermXml = new HashSet(gwtCompiledFiles);
namesForPermXml.addAll(otherResources);
try {
return xmlPermutationProvider.writePermutationInformation(permutationArtifact.getPermutationName(),
permutationArtifact.getBindingProperties(), namesForPermXml);
} catch (XMLPermutationProviderException e) {
logger.log(Type.ERROR, "can not build xml for permutation file", e);
throw new UnableToCompleteException();
}
}
/**
* @param permutationArtifactAsMap
* @return
*/
protected Set getAllPermutationFiles(Map permutationArtifactAsMap) {
Set allPermutationFiles = new HashSet();
for (Entry entry : permutationArtifactAsMap.entrySet()) {
allPermutationFiles.addAll(entry.getValue().getPermutationFiles());
}
return allPermutationFiles;
}
protected Map getPermutationArtifactAsMap(ArtifactSet artifacts) {
Map hashMap = new HashMap();
for (PermutationArtifact permutationArtifact : artifacts.find(PermutationArtifact.class)) {
hashMap.put(permutationArtifact.getPermutationName(), permutationArtifact);
}
return hashMap;
}
protected boolean shouldArtifactBeInManifest(String pathName) {
if (pathName.endsWith("symbolMap") || pathName.endsWith(".xml.gz") || pathName.endsWith("rpc.log")
|| pathName.endsWith("gwt.rpc") || pathName.endsWith("manifest.txt")
|| pathName.startsWith("rpcPolicyManifest") || pathName.startsWith("soycReport")
|| pathName.endsWith(".cssmap") || pathName.endsWith("hosted.html")) {
return false;
}
// TODO reg exp
return true;
}
protected Set getArtifactsForCompilation(TreeLogger logger, LinkerContext context, ArtifactSet artifacts) {
Set artifactNames = new HashSet();
for (EmittedArtifact artifact : artifacts.find(EmittedArtifact.class)) {
String pathName = artifact.getPartialPath();
if (shouldArtifactBeInManifest(pathName)) {
artifactNames.add(context.getModuleName() + "/" + pathName.replace('\\', '/'));
}
}
return artifactNames;
}
protected String buildManiFest(String moduleName, Set cacheResources, Set externalFiles) {
return manifestWriter.writeManifest(externalFiles, cacheResources);
}
protected Set getExternalFiles(TreeLogger logger, LinkerContext context) {
HashSet set = new HashSet();
SortedSet properties = context.getConfigurationProperties();
for (ConfigurationProperty configurationProperty : properties) {
String name = configurationProperty.getName();
if (EXTERNAL_FILES_CONFIGURATION_PROPERTY_NAME.equals(name)) {
for (String value : configurationProperty.getValues()) {
set.add(value);
}
}
}
return set;
}
protected EmittedArtifact createPermutationMap(TreeLogger logger, Map> map)
throws UnableToCompleteException {
try {
String string = xmlPermutationProvider.serializeMap(map);
return emitString(logger, string, MANIFEST_MAP_FILE_NAME);
} catch (XMLPermutationProviderException e) {
logger.log(Type.ERROR, "can not build manifest map", e);
throw new UnableToCompleteException();
}
}
protected Map> buildPermutationMap(TreeLogger logger, LinkerContext context,
ArtifactSet artifacts) throws UnableToCompleteException {
HashMap> map = new HashMap>();
for (SelectionInformation result : artifacts.find(SelectionInformation.class)) {
Set list = new HashSet();
map.put(result.getStrongName(), list);
TreeMap propMap = result.getPropMap();
Set> set = propMap.entrySet();
for (Entry entry : set) {
BindingProperty bindingProperty = new BindingProperty(entry.getKey(), entry.getValue());
list.add(bindingProperty);
}
}
return map;
}
}