- 
                Notifications
    You must be signed in to change notification settings 
- Fork 56
Class Tag
        Ori Roth edited this page Apr 2, 2017 
        ·
        3 revisions
      
    public class Tag { 
    /*
     * Forge (14)
     */
        Tag(String name, String[] flags); 
        Tag(Tag inner, String name, String[] flags); 
        final static Tag strong; 
        final static Tag em; 
        final static Tag pre; 
        final static Tag tt; 
        final static Tag p; 
        final static Tag u; 
        final static Tag h1; 
        final static Tag h2; 
        final static Tag h3; 
        final static Tag h4; 
        final static Tag h5; 
        final static Tag h6; 
    /*
     * Type (8)
     */
        String wrap(String s); 
        String wrapNL(String s); 
        Tag inside(String name, String[] flags); 
        String makeRegularExpression(); 
        Pattern makePattern(); 
        Matcher makeMatcher(String s); 
        final String begin; 
        final String end; 
    /*
     * Utilities (5)
     */
        static String replace(String text, String from, String to); 
        static String remove(String text, String tag); 
        static String beginTag(String name); 
        static String selfClosing(String name); 
        static String endTag(String name); 
    /*
     * Nested types (1)
     */
        static class TestMakePattern { ... } 
}Output types: Matcher, Pattern.
public static class Tag.TestMakePattern { 
    /*
     * Forge (1)
     */
        TestMakePattern(); 
    /*
     * Type (8)
     */
        void testSimplePre(); 
        void testEmptyPre(); 
        void testCRLFinPre(); 
        void testLFinPre(); 
        void testSeveralLinesInPre(); 
        void testUpperCaseTag(); 
        void testMiXeDCaSeTag(); 
        void testDummyInContext(); 
} // SSDLPedia
package il.ac.technion.cs.ssdl.strings;
import static il.ac.technion.cs.ssdl.strings.RE.anyNumberOfReluctant;
import static il.ac.technion.cs.ssdl.strings.RE.group;
import static il.ac.technion.cs.ssdl.strings.RE.ignoreCase;
import static il.ac.technion.cs.ssdl.utils.DBC.nonnull;
import static org.junit.Assert.assertEquals;
import il.ac.technion.cs.ssdl.stereotypes.Immutable;
import il.ac.technion.cs.ssdl.stereotypes.Instantiable;
import il.ac.technion.cs.ssdl.utils.Separate;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.junit.Test;
/**
 * A representation of an HTML tag, capable of wrapping a given String.
 * 
 * Author: Yossi Gil, the Technion.
 * See:  11/07/2008
 */
@Immutable @Instantiable public class Tag {
    /**
     * Wrap a given string within this tag.
     * 
     * s a non-null representing the string to wrap
     * Return: the string s wrapped with the tag, e.g., if
     *         s is "Hello" and the tag name is
     *         "b" then "Hello"" is returned.
     */
    public String wrap(final String s) {
        nonnull(s);
        return s.length() == 0 ? s : begin + s + end;
    }
    
    /**
     * Wrap a given string within newline characters and then within this tag.
     * 
     * s a non-null representing the string to wrap
     * Return: the string s wrapped with the tag, e.g., if
     *         s is "Hello" and the tag name is
     *         "b" then the string "\nHello\n"
     *         is returned.
     */
    public String wrapNL(final String s) {
        nonnull(s);
        return wrap("\n" + s + "\n");
    }
    
    /**
     * Instantiate a plain tag, i.e., a tag without any inner tags,
     * 
     * name the tag name, e.g., "font"
     * flags any number of HTML flags
     */
    public Tag(final String name, final String... flags) {
        nonnull(name);
        nonnull(flags);
        begin = beginTag(name + (flags.length == 0 ? "" : " " + Separate.by(flags, " ")));
        end = beginTag("/" + name);
    }
    
    /**
     * Instantiate a tag containing another tag
     * 
     * inner the inner tag; all instances of the newly created tag will
     *            be around this inner tag
     * name the tag name, e.g., "font"
     * flags any number of HTML flags
     */
    public Tag(final Tag inner, final String name, final String... flags) {
        nonnull(name);
        nonnull(flags);
        final Tag unnested = new Tag(name, flags);
        begin = unnested.begin + inner.begin;
        end = inner.end + unnested.end;
    }
    
    /**
     * A factory function, creating a new tag, containing this one. Typical use
     * demonstrates tag containment. The expression
       new Tag("strong").inside("tt")
     * returns a newly created nested Tag composed of a strong
     * within a tt tag.
     * 
     * name the name of the newly created tag, e.g., "font"
     * flags any number of HTML flags to be used with the newly created
     *            tag
     * Return: A newly created tag with the specified name and flags, containing
     *         this tag
     */
    public Tag inside(final String name, final String... flags) {
        return new Tag(this, name, flags);
    }
    
    /**
     * Make a regular expression to capture the opening and closing tag together
     * with the enclosed content.
     * 
     * Return: a regular expression to capture the tag and its content. The
     *         content is in group number 1.
     */
    public String makeRegularExpression() {
        return ignoreCase() + begin + group(anyNumberOfReluctant(".|[\r\n]")) + end;
    }
    
    /**
     * Make a Pattern to capture the opening and closing tag together
     * with the enclosed content.
     * 
     * Return: a regular expression to capture the tag and its content. The
     *         content is in group number 1.
     */
    public Pattern makePattern() {
        return Pattern.compile(makeRegularExpression());
    }
    
    /**
     * Make a Matcher of a given text, to capture the opening and
     * closing tag together with the enclosed content in this text.
     * 
     * s where to look for this text?
     * Return: Matcher of the parameter to capture the tag and its
     *         content. The content is in group number 1.
     */
    public Matcher makeMatcher(final String s) {
        return makePattern().matcher(s);
    }
    
    /**
     * The opening String of this tag.
     */
    public final String begin;
    /**
     * The closing String of this tag.
     */
    public final String end;
    /**
     * A pre-made instance, representing the HTML <strong> tag.
     */
    public final static Tag strong = new Tag("strong");
    /**
     * A pre-made instance, representing the HTML <em> tag.
     */
    public final static Tag em = new Tag("em");
    /**
     * A pre-made instance, representing the HTML <pre> tag.
     */
    public final static Tag pre = new Tag("pre");
    /**
     * A pre-made instance, representing the HTML <tt> tag.
     */
    public final static Tag tt = new Tag("tt");
    /**
     * A pre-made instance, representing the HTML <p> tag, used for
     * marking a paragraph.
     */
    public final static Tag p = new Tag("p");
    /**
     * A pre-made instance, representing the HTML <u> tag, used for
     * underlining the wrapped text.
     */
    public final static Tag u = new Tag("u");
    /**
     * A pre-made instance, representing the HTML <h1> tag.
     */
    public final static Tag h1 = new Tag("h1");
    /**
     * A pre-made instance, representing the HTML <h2> tag.
     */
    public final static Tag h2 = new Tag("h2");
    /**
     * A pre-made instance, representing the HTML <h3> tag.
     */
    public final static Tag h3 = new Tag("h3");
    /**
     * A pre-made instance, representing the HTML <h4> tag.
     */
    public final static Tag h4 = new Tag("h4");
    /**
     * A pre-made instance, representing the HTML <h5> tag.
     */
    public final static Tag h5 = new Tag("h5");
    /**
     * A pre-made instance, representing the HTML <h6> tag.
     */
    public final static Tag h6 = new Tag("h6");
    
    public static String replace(final String text, final String from, final String to) {
        return text//
                .replaceAll(ignoreCase() + beginTag(from), beginTag(to)) //
                .replaceAll(ignoreCase() + endTag(from), endTag(to));
    }
    
    public static String remove(final String text, final String tag) {
        return text//
                .replaceAll(ignoreCase() + beginTag(tag), "") //
                .replaceAll(ignoreCase() + endTag(tag), "") //
                .replaceAll(ignoreCase() + selfClosing(tag), "") //
        ;
    }
    
    /**
     * Make a String of an HTML opening tag with a given name.
     * 
     * name the name of the given tag.
     * Return: the name enclosed in angular brackets.
     */
    public static String beginTag(final String name) {
        return "<" + name + ">";
    }
    
    /**
     * Make a self closing String of an HTML tag with a given name.
     * 
     * name the name of the given tag.
     * Return: the name parameter, followed by slash (/) and enclosed in angular
     *         brackets.
     */
    public static String selfClosing(final String name) {
        return beginTag(name + " /");
    }
    
    /**
     * Make a String of an HTML closing tag with a given name.
     * 
     * name the name of the given tag.
     * Return: the name enclosed in angular brackets.
     */
    public static String endTag(final String name) {
        return beginTag("/" + name);
    }
    
    public static class TestMakePattern {
        private static final String tagRegularExpression = new Tag("dummy").makeRegularExpression();
        
        @Test public void testSimplePre() {
            assertEquals("ABC", "A<dummy>X</dummy>C".replaceFirst(tagRegularExpression, "B"));
        }
        
        @Test public void testEmptyPre() {
            assertEquals("ABC", "A<dummy></dummy>C".replaceFirst(tagRegularExpression, "B"));
        }
        
        @Test public void testCRLFinPre() {
            assertEquals("ABC", "A<dummy>\r\n</dummy>C".replaceFirst(tagRegularExpression, "B"));
        }
        
        @Test public void testLFinPre() {
            assertEquals("ABC", "A<dummy>\n</dummy>C".replaceFirst(tagRegularExpression, "B"));
        }
        
        @Test public void testSeveralLinesInPre() {
            assertEquals("ABC", "A<dummy>a\nb\r\nABCDE</dummy>C".replaceFirst(tagRegularExpression, "B"));
        }
        
        @Test public void testUpperCaseTag() {
            assertEquals("ABC", "A<DUMMY>a\nb\r\nABCDE</DUMMY>C".replaceFirst(tagRegularExpression, "B"));
        }
        
        @Test public void testMiXeDCaSeTag() {
            assertEquals("ABC", "A<DuMmY>a\nb\r\nABCDE</dUmMy>C".replaceFirst(tagRegularExpression, "B"));
        }
        
        @Test public void testDummyInContext() {
            assertEquals("" + //
                    "\t /**\r\n" + //
                    "\t  * BEFORE\r\n" + //
                    "\t  * Content\r\n" + //
                    "\t  * AFTER\r\n" + //
                    "\t  */" + //
                    "", ("" + //
                    "\t /**\r\n" + // 
                    "\t  * BEFORE\r\n" + //
                    "\t  * <dummy>\r\n" + //
                    "\t  * text\r\n" + //
                    "\t  * </dummy>\r\n" + //
                    "\t  * AFTER\r\n" + //
                    "\t  */" + //
                    "").replaceFirst(tagRegularExpression, "Content"));
        }
    }
}| Metric | Value | Acronym | Explanation | 
|---|---|---|---|
| LOC | 290 | Lines Of Code | Total number of lines in the code | 
| SCC | 57 | SemiColons Count | Total number of semicolon tokens found in the code. | 
| NOT | 997 | Number Of Tokens | Comments, whitespace and text which cannot be made into a token not included. | 
| VCC | 7118 | Visible Characters Count | The total number of non-white (i.e., not space, tab, newline, carriage return, form feed) characters. | 
| CCC | 3713 | Code Characters Count | Total number of non-white characters in tokens. White space characters in string and character literals are not counted. | 
| UIC | 79 | Unique Identifiers Count | The number of different identifiers found in the code | 
| WHC | 4 | Weighted Horizontal Complexity | A heuritistic on horizontal complexity | 
| Statistic | Value | 
|---|---|
| Average token length | 3.7 | 
| Tokens/line | 3.4 | 
| Visible characters/line | 25 | 
| Code characters/line | 13 | 
| Semicolons/tokens | 5% | 
| Comment text percentage | 47% | 
Tokens by kind
| Token Kind | Occurrences | 
|---|---|
| KEYWORD | 145 | 
| OPERATOR | 57 | 
| LITERAL | 67 | 
| ID | 313 | 
| PUNCTUATION | 415 | 
| COMMENT | 47 | 
| OTHER | 525 |