File: UrlRewritingTokenizer.java

package info (click to toggle)
liblessen-java 1.0-2
  • links: PTS, VCS
  • area: main
  • in suites: bookworm, forky, sid, trixie
  • size: 276 kB
  • sloc: java: 2,981; xml: 31; makefile: 5
file content (114 lines) | stat: -rw-r--r-- 3,713 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
package com.metaweb.lessen.tokenizers;

import com.metaweb.lessen.tokens.Token;
import com.metaweb.lessen.tokens.UriToken;
import com.metaweb.lessen.tokens.Token.Type;


public class UrlRewritingTokenizer implements Tokenizer {
    final protected Tokenizer   _tokenizer;
    final protected String      _relativePath;
    final protected String[]    _segments;
    protected Token             _token;
    
    /**
     * relativePath specifies how to get from the output CSS's URL to
     * the input CSS's URL. For example, say the input CSS is served at
     * 
     *   some-path/modules/foo/styles/detail-page.css
     * 
     * which is to be bundled with other CSS files to produce a CSS
     * bundle to be served at
     * 
     *   some-path/bundles/foo.css
     *   
     * then the relative path is
     * 
     *   ../modules/foo/styles/
     *   
     * because from foo.css, we need to go up one directory level to
     * some-path, and then down modules/foo/styles/ to get to
     * detail-page.css. If detail-page.css contains
     * 
     *   url(../images/watermark.png)
     * 
     * then it'll be resolved to
     * 
     *   url(../modules/foo/images/watermark.png)
     *   
     * in foo.css so that foo.css effectively references the same image.
     * 
     * @param tokenizer
     * @param relativePath
     */
    public UrlRewritingTokenizer(Tokenizer tokenizer, String relativePath) {
        _tokenizer = tokenizer;
        _relativePath = relativePath;
        
        if (relativePath.endsWith("/")) {
            relativePath = relativePath.substring(0, relativePath.length() - 1);
        }
        _segments = _relativePath.split("/");
        
        _token = _tokenizer.getToken();
        resolve();
    }
    
    @Override
    public Token getToken() {
        return _token;
    }

    @Override
    public void next() {
        _tokenizer.next();
        _token = _tokenizer.getToken();
        resolve();
    }
    
    protected void resolve() {
        if (_token != null && _token.type == Type.Uri) {
            UriToken t = (UriToken) _token;
            if (t.prefix.equals("url")) {
                String url = t.unquotedText;
                if (url.indexOf("://") < 0 && !url.startsWith("/")) { // not absolute URLs
                    int lastSegment = _segments.length;
                    while (url.length() > 0) {
                        if (url.startsWith("./")) {
                            url = url.substring(2);
                        } else if (url.startsWith("../")) {
                            url = url.substring(3);
                            lastSegment--;
                        } else {
                            break;
                        }
                    }
                    
                    StringBuffer sb = new StringBuffer();
                    if (lastSegment > 0) {
                        for (int i = 0; i < lastSegment; i++) {
                            sb.append(_segments[i]);
                            sb.append('/');
                        }
                    } else {
                        while (lastSegment < 0) {
                            sb.append("../");
                            lastSegment++;
                        }
                    }
                    
                    String url2 = sb.toString() + url;
                    String text = t.prefix + "(\"" + url2 + "\")";
                    
                    _token = new UriToken(
                        t.start,
                        t.end,
                        text,
                        t.prefix,
                        url2
                    );
                }
            }
        }
    }
}