Skip to content
This repository has been archived by the owner on Feb 23, 2022. It is now read-only.

Add Customized Splitter instead of hard code character '-' #76

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
50 changes: 42 additions & 8 deletions src/com/google/common/css/SplittingSubstitutionMap.java
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@

package com.google.common.css;

import com.google.common.annotations.VisibleForTesting;
import com.google.common.base.Preconditions;
import com.google.common.base.Splitter;
import com.google.common.collect.ImmutableMap;
Expand All @@ -24,19 +25,52 @@
import java.util.Map;

/**
* The CSS class substitution map which splits CSS class names on the "-" (dash)
* character and processes them separately using a delegate substitution map.
* <p>The CSS class substitution map which splits CSS class names on the "-" (dash)
* character and processes them separately using a delegate substitution map.</p>
*
* <p>At the same time, if customized splitter character is assigned, the CSS class
* substitution map will splits CSS class names on the specific character;</p>
*
* @author [email protected] (Damian Gajda)
*/
public class SplittingSubstitutionMap implements
MultipleMappingSubstitutionMap {
private static final Splitter DASH = Splitter.on('-');
public static final char DEFAULT_CSS_CLASS_SPLITTER_CHAR = '-';
private static final Splitter DEFAULT_CSS_CLASS_SPLITTER = Splitter.
on(DEFAULT_CSS_CLASS_SPLITTER_CHAR);
private final SubstitutionMap delegate;


/**
* Make splitter become configurable. The value can be decided by the option
* user input. Default value is dash character '-'.
*/
private char splitterChar = DEFAULT_CSS_CLASS_SPLITTER_CHAR;
private Splitter splitter = DEFAULT_CSS_CLASS_SPLITTER;

public SplittingSubstitutionMap(SubstitutionMap substitutionMap) {
this.delegate = substitutionMap;
}

/**
* Please NOTE: this method is used as internal method when developers want to
* introduce customized css class splitter. So do not call it manually.
*
* @param splitterChar The customized splitter you need.
*/
public void registerSplitter(char splitterChar) {
this.splitterChar = splitterChar;
this.splitter = Splitter.on(splitterChar);
}

/**
* Please NOTE: this method is used as testing method. So do not call it manually.
*
* @return splitterChar
*/
@VisibleForTesting
public char getSplitterChar() {
return splitterChar;
}

@Override
public String get(String key) {
Expand All @@ -48,8 +82,8 @@ public ValueWithMappings getValueWithMappings(String key) {
Preconditions.checkNotNull(key, "CSS key cannot be null");
Preconditions.checkArgument(!key.isEmpty(), "CSS key cannot be empty");

// Efficiently handle the common case with no dashes.
if (key.indexOf('-') == -1) {
// Efficiently handle the common case with no specific splitter character.
if (key.indexOf(this.splitterChar) == -1) {
String value = delegate.get(key);
return ValueWithMappings.createForSingleMapping(key, value);
}
Expand All @@ -58,9 +92,9 @@ public ValueWithMappings getValueWithMappings(String key) {
// Cannot use an ImmutableMap.Builder because the same key/value pair may be
// inserted more than once in this loop.
Map<String, String> mappings = Maps.newHashMap();
for (String part : DASH.split(key)) {
for (String part : splitter.split(key)) {
if (buffer.length() != 0) {
buffer.append('-');
buffer.append(this.splitterChar);
}

String value = delegate.get(part);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,8 @@
import com.google.common.css.JobDescriptionBuilder;
import com.google.common.css.OutputRenamingMapFormat;
import com.google.common.css.SourceCode;
import com.google.common.css.SplittingSubstitutionMap;
import com.google.common.css.SubstitutionMap;
import com.google.common.css.Vendor;
import com.google.common.css.compiler.ast.ErrorManager;
import com.google.common.css.compiler.gssfunctions.DefaultGssFunctionMapProvider;
Expand Down Expand Up @@ -62,6 +64,9 @@
*/
public class ClosureCommandLineCompiler extends DefaultCommandLineCompiler {

private static final String DEFAULT_CSS_CLASS_SLIPPTER_SINGLE_CHARACTER_STRING =
String.valueOf(SplittingSubstitutionMap.DEFAULT_CSS_CLASS_SPLITTER_CHAR);

protected ClosureCommandLineCompiler(JobDescription job,
ExitCodeHandler exitCodeHandler, ErrorManager errorManager) {
super(job, exitCodeHandler, errorManager);
Expand Down Expand Up @@ -202,6 +207,12 @@ static class Flags {
usage = "Specify integer constants to be used in for loops. Invoke for each const, e.g.: "
+ "--const=VAR1=VALUE1 --const=VAR2=VALUE2")
private Map<String, String> compileConstants = new HashMap<>();

@Option(name = "--css-class-splitter",
usage = "Define your single-character customized splitter when process "
+ "css class names. Default value is '-'. If you want to enable this feature, "
+ "please choose 'DEBUG' or 'CLOSURE' for '--rename'")
private String splitter = DEFAULT_CSS_CLASS_SLIPPTER_SINGLE_CHARACTER_STRING;

/**
* All remaining arguments are considered input CSS files.
Expand Down Expand Up @@ -283,6 +294,43 @@ private Map<String, Integer> parseCompileConstants(
}
return parsedConstants;
}

/**
* Only following requirements are satisfied, the customized splitter will
* be used:
* <ul>
* <li>
* Option <code>css-class-splitter</code> is NOT Null or empty;
* </li>
* <li>
* Option <code>css-class-splitter</code> only contains <b>ONE</b> character;
* </li>
* <li>
* Option <code>css-class-splitter</code> doesn't equal to default value <b>'-'</b>;
* </li>
* <li>
* Option <code>renamingType</code> is <b>RenamingType.CLOSURE</b> or
* <b>RenamingType.DEBUG</b>;
* </li>
* </ul>
*/
@VisibleForTesting
void registerSplitterIfExist() {
if (!Strings.isNullOrEmpty(splitter)
&& !splitter.equals(DEFAULT_CSS_CLASS_SLIPPTER_SINGLE_CHARACTER_STRING)
&& (renamingType.equals(RenamingType.CLOSURE)
|| renamingType.equals(RenamingType.DEBUG))) {
SubstitutionMap map = renamingType.getCssSubstitutionMapProvider().get();
if (map instanceof SplittingSubstitutionMap) {
((SplittingSubstitutionMap)map).registerSplitter(splitter.charAt(0));
}
}
}

@VisibleForTesting
RenamingType getRenamingType() {
return renamingType;
}
}

/**
Expand Down Expand Up @@ -386,8 +434,16 @@ public void printUsage(OutputStream out) {
return null;
}

boolean errorHappen = false;
if (!Strings.isNullOrEmpty(flags.splitter) && flags.splitter.length() > 1) {
System.err.println("\nERROR: Only single character is supported for --css-class-splitter.\n");
errorHappen = true;
}
if (flags.arguments.isEmpty()) {
System.err.println("\nERROR: No input files specified.\n");
errorHappen = true;
}
if (errorHappen) {
argsParser.printUsage(System.err);
exitCodeHandler.processExitCode(
AbstractCommandLineCompiler.ERROR_MESSAGE_EXIT_CODE);
Expand All @@ -404,6 +460,7 @@ public static void main(String[] args) {
return;
}

flags.registerSplitterIfExist();
JobDescription job = flags.createJobDescription();
OutputInfo info = flags.createOutputInfo();
executeJob(job, exitCodeHandler, info);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,8 +52,9 @@ public SubstitutionMap get() {


/**
* Each chunk of a CSS class as delimited by '-' is renamed using the
* shortest available name.
* Each chunk of a CSS class as delimited by specific splitter is
* renamed using the shortest available name. Default specific
* splitter is '-'.
*/
CLOSURE(new SubstitutionMapProvider() {
@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,13 +19,16 @@
import com.google.common.css.JobDescription;
import com.google.common.css.JobDescriptionBuilder;
import com.google.common.css.SourceCode;
import com.google.common.css.SplittingSubstitutionMap;
import com.google.common.css.compiler.ast.ErrorManager;
import com.google.common.css.compiler.ast.testing.NewFunctionalTestBase;

import junit.framework.TestCase;

public class ClosureCommandLineCompilerTest extends TestCase {

private static final String TEST_SPLITTER = "-";

static final ExitCodeHandler EXIT_CODE_HANDLER =
new ExitCodeHandler() {
@Override
Expand Down Expand Up @@ -64,4 +67,17 @@ public void testAllowDefPropagationDefaultsToTrue() throws Exception {
JobDescription jobDescription = flags.createJobDescription();
assertTrue(jobDescription.allowDefPropagation);
}

public void testAssignCustomizedSplitter() throws Exception {
ClosureCommandLineCompiler.Flags flags =
ClosureCommandLineCompiler.parseArgs(new String[] {"--allow-unrecognized-functions",
"--allow-unrecognized-properties", "--rename", "CLOSURE",
"--css-class-splitter", TEST_SPLITTER, "/dev/null"}, EXIT_CODE_HANDLER);
flags.registerSplitterIfExist();
assertEquals("Type of RenamingType should be CLOSURE",
flags.getRenamingType().name(), "CLOSURE");
assertEquals("The passed splitter should be the same as it in test case.",
TEST_SPLITTER.charAt(0),
((SplittingSubstitutionMap)(flags.getRenamingType().getCssSubstitutionMapProvider().get())).getSplitterChar());
}
}