Project

General

Profile

Download (6.15 KB) Statistics
| Branch: | Tag: | Revision:
1
/**
2
* Copyright (C) 2015 EDIT
3
* European Distributed Institute of Taxonomy
4
* http://www.e-taxonomy.eu
5
*
6
* The contents of this file are subject to the Mozilla Public License Version 1.1
7
* See LICENSE.TXT at the top of this package for the full license terms.
8
*/
9
package eu.etaxonomy.cdm.strategy.cache;
10

    
11
import java.util.ArrayList;
12
import java.util.EnumSet;
13
import java.util.List;
14
import java.util.SortedSet;
15
import java.util.Stack;
16
import java.util.TreeSet;
17

    
18
import org.apache.commons.lang3.StringUtils;
19

    
20
/**
21
 * Formatter class to create Strings from TaggedText Lists.
22
 *
23
 * @author a.mueller
24
 * @since 09.09.2015
25
 */
26
public class TaggedCacheHelper {
27

    
28
    private static final TaggedText WHITESPACE_TAG = TaggedText.NewWhitespaceInstance();
29

    
30
    /**
31
     * Creates a string from tagged text by concatenating all tags with a whitespace.
32
     * @param tags
33
     * @return the concatenated string
34
     * @see #createString(List, HTMLTagRules)
35
     */
36
    public static String createString(List<? extends TaggedText> tags) {
37
        return createString(tags, null);
38
    }
39
    /**
40
     * Creates a string from tagged text by concatenating all tags with a whitespace.
41
     * @param tags
42
     *  The TaggedText elements
43
     * @param excludes
44
     *  Set up {@link TagEnum}s to remove from the resulting text
45
     * @return the concatenated string
46
     * @see #createString(List, HTMLTagRules)
47
     */
48
    public static String createString(List<? extends TaggedText> tags, EnumSet<TagEnum> excludes) {
49
        StringBuilder result = new StringBuilder();
50

    
51
        boolean isSeparator;
52
        boolean wasSeparator = true;  //true for start tag
53
        int index = 0;
54
        for (index = 0; index < tags.size(); index++){
55
            TaggedText tag = tags.get(index);
56
            if(excludes != null && excludes.contains(tag.getType())) {
57
                continue;
58
            }
59
            isSeparator = tag.getType().isSeparator();
60
            if (! wasSeparator && ! isSeparator ){
61
                result.append(" ");
62
            }
63
            if (index < tags.size() -1 || tag.getType() != TagEnum.postSeparator ){
64
                result.append(tag.getText());
65
            }
66
            wasSeparator = isSeparator;
67
        }
68
        return result.toString().trim();
69
    }
70

    
71
    /**
72
     * Creates a string from tagged text by concatenating all tags. If no separator tag is defined
73
     * tags are separated by simple whitespace.
74
     */
75
    public  static String createString(List<TaggedText> tagsOrigin, HTMLTagRules htmlRules) {
76
        if (htmlRules == null){
77
            return createString(tagsOrigin);
78
        }
79
        List<TaggedText> tags = new ArrayList<>(tagsOrigin);
80

    
81
        //add whitespace separators
82
        int index = 0;
83
        boolean wasSeparator = true;
84
        while (index < tags.size()){
85

    
86
            if (! tags.get(index).getType().isSeparator()){
87
                if (wasSeparator == false){
88
                    tags.add(index++, WHITESPACE_TAG);
89
                }else{
90
                    wasSeparator = false;
91
                }
92
            }else{
93
                wasSeparator = true;
94
            }
95
            index++;
96
        }
97

    
98
        //create String
99
        StringBuffer result = new StringBuffer();
100

    
101
        Stack<String> htmlStack = new Stack<>();
102
        for (int i = 0;  i < tags.size(); i++  ){
103
            TaggedText tag = tags.get(i);
104
            TaggedText lastTag = (i == 0? null : tags.get(i - 1));
105
            TaggedText nextTag = (i + 1 >= tags.size() ? null : tags.get(i + 1));
106
            TagEnum lastType = (lastTag == null ? null : lastTag.getType());
107
            TagEnum nextType = (nextTag == null ? null : nextTag.getType());
108

    
109
            boolean isSeparator = tag.getType().isSeparator();
110
            boolean isBlankSeparator = isSeparator && StringUtils.isBlank(tag.getText());
111

    
112
            //compute list of rules (tags)
113
            SortedSet<String> separatorRules;
114
            if (isBlankSeparator){
115
                separatorRules = getCommonRules(htmlRules.getRule(lastTag), htmlRules.getRule(nextTag));
116
            }else{
117
                separatorRules = htmlRules.getRule(tag);
118
            }
119

    
120
            //Close all tags not used anymore and remove all common tags from list of rules
121
            for (int j = 0 ;  j < htmlStack.size() ; j++){
122
                String html = htmlStack.get(j);
123
                if (! separatorRules.contains(html)){
124
                    closeHtml(result, htmlStack, j);
125
                    break;
126
                }else{
127
                    separatorRules.remove(html);
128
                }
129
            }
130

    
131
            //open all tags not yet existing
132
            if (! isBlankSeparator){
133
                for (String rule : separatorRules){
134
                    htmlStack.add(rule);
135
                    result.append("<" +  rule + ">");
136
                }
137
            }
138

    
139
            //add whitespace
140
            if (!isSeparator && lastType != null && !lastType.isSeparator() && nextType != null){
141
                result.append(" ");
142
            }
143
            result.append(tag.getText());
144
        }
145
        closeHtml(result, htmlStack, 0);
146
        return result.toString();
147
    }
148

    
149
    /**
150
     * tries to find a tagged text elements that matches the <code>type</code> and <code>textRegex</code> and
151
     * returns all preceding elements as sublist.
152
     */
153
    public static List<? extends TaggedText> cropAt(List<? extends TaggedText> tags, TagEnum type, String textRegex) {
154
        int pos = 0;
155
        for (TaggedText taggedText : tags) {
156
            if(type.equals(taggedText.getType()) && taggedText.getText().matches(textRegex)) {
157
                break;
158
            }
159
            pos++;
160
        }
161
        return tags.subList(0, pos);
162
    }
163

    
164

    
165
    private static void closeHtml(StringBuffer result, Stack<String> htmlStack, int index) {
166
        while (htmlStack.size() > index){
167
            String closeHtml = htmlStack.pop();
168
            result.append("</" +  closeHtml + ">");
169
        }
170
    }
171

    
172
    private static SortedSet<String> getCommonRules(SortedSet<String> rules1,SortedSet<String> rules2) {
173
        SortedSet<String> result = new TreeSet<>();
174
        for (String str : rules1){
175
            if (rules2.contains(str)){
176
                result.add(str);
177
            }
178
        }
179
        return result;
180
    }
181
}
(3-3/5)