~ubuntu-branches/ubuntu/oneiric/jing-trang/oneiric

« back to all changes in this revision

Viewing changes to mod/convert-to-dtd/src/main/com/thaiopensource/relaxng/output/dtd/ModelBreaker.java

  • Committer: Bazaar Package Importer
  • Author(s): Samuel Thibault
  • Date: 2009-09-01 15:53:03 UTC
  • Revision ID: james.westby@ubuntu.com-20090901155303-2kweef05h5v9j3ni
Tags: upstream-20090818
ImportĀ upstreamĀ versionĀ 20090818

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
package com.thaiopensource.relaxng.output.dtd;
 
2
 
 
3
import java.util.NoSuchElementException;
 
4
 
 
5
class ModelBreaker {
 
6
  private boolean done = false;
 
7
  private BreakIterator iter;
 
8
  private final String prefix;
 
9
  private final String model;
 
10
  private final String suffix;
 
11
  private final int maxLineLength;
 
12
  private int modelPos;
 
13
  private ModelBreaker nested = null;
 
14
 
 
15
  private static class BreakIterator {
 
16
    private final String model;
 
17
    private int pos = 0;
 
18
    private final int length;
 
19
 
 
20
    BreakIterator(String model) {
 
21
      this.model = model;
 
22
      this.length = model.length();
 
23
    }
 
24
 
 
25
    int getPos() {
 
26
      return pos;
 
27
    }
 
28
 
 
29
    boolean advance() {
 
30
      boolean advanced = false;
 
31
      int level = 0;
 
32
      for (; pos < length; pos++) {
 
33
        switch (model.charAt(pos)) {
 
34
        case '(':
 
35
          level++;
 
36
          break;
 
37
        case ')':
 
38
          level--;
 
39
          break;
 
40
        case ',':
 
41
          if (level != 0)
 
42
            break;
 
43
          if (++pos != length)
 
44
            return true;
 
45
          break;
 
46
        case '|':
 
47
          if (level != 0 || !advanced)
 
48
            break;
 
49
          return true;
 
50
        case ' ':
 
51
          if (level != 0 || !advanced)
 
52
            break;
 
53
          return true;
 
54
        }
 
55
        advanced = true;
 
56
      }
 
57
      return false;
 
58
    }
 
59
  }
 
60
 
 
61
  ModelBreaker(String prefix, String model, String suffix, int maxLineLength) {
 
62
    if (isSingleGroup(model)) {
 
63
      int open = model.indexOf('(') + 1;
 
64
      this.prefix = prefix + model.substring(0, open);
 
65
      this.model = model.substring(open);
 
66
    }
 
67
    else {
 
68
      this.prefix = prefix;
 
69
      this.model = model;
 
70
    }
 
71
    this.suffix = suffix;
 
72
    this.maxLineLength = maxLineLength;
 
73
    this.modelPos = 0;
 
74
  }
 
75
 
 
76
  boolean hasNextLine() {
 
77
    if (nested != null && nested.hasNextLine())
 
78
      return true;
 
79
    return !done;
 
80
  }
 
81
 
 
82
  String nextLine() {
 
83
    if (nested != null && nested.hasNextLine())
 
84
      return nested.nextLine();
 
85
    if (done)
 
86
      throw new NoSuchElementException();
 
87
    int avail = maxLineLength - prefix.length();
 
88
    int breakPos;
 
89
    boolean tooBig = false;
 
90
    if ((model.length() - modelPos) + suffix.length() > avail) {
 
91
      if (iter == null)
 
92
        iter = new BreakIterator(model);
 
93
      breakPos = -1;
 
94
      do {
 
95
        int pos = iter.getPos();
 
96
        if (pos >= model.length())
 
97
          break;
 
98
        int w = pos - modelPos;
 
99
        if (w > 0) {
 
100
          if (w > avail) {
 
101
            if (breakPos == -1) {
 
102
              breakPos = pos;
 
103
              tooBig = true;
 
104
            }
 
105
            break;
 
106
          }
 
107
          breakPos = pos;
 
108
        }
 
109
      } while (iter.advance());
 
110
      if (breakPos == -1) {
 
111
        tooBig = true;
 
112
        breakPos = model.length();
 
113
      }
 
114
    }
 
115
    else
 
116
      breakPos = model.length();
 
117
    int nextModelPos;
 
118
    if (breakPos < model.length() && model.charAt(breakPos) == ' ')
 
119
      nextModelPos = breakPos + 1;
 
120
    else
 
121
      nextModelPos = breakPos;
 
122
    StringBuffer buf = new StringBuffer();
 
123
    if (modelPos == 0)
 
124
      buf.append(prefix);
 
125
    else {
 
126
      for (int i = 0, len = prefix.length(); i < len; i++)
 
127
        buf.append(' ');
 
128
    }
 
129
    if (tooBig && (modelPos != 0 || breakPos != model.length())) {
 
130
      String nestSuffix;
 
131
      if (breakPos == model.length()) {
 
132
        done = true;
 
133
        nestSuffix = suffix;
 
134
      }
 
135
      else
 
136
        nestSuffix = "";
 
137
      nested = new ModelBreaker(buf.toString(), model.substring(modelPos, breakPos), nestSuffix, maxLineLength);
 
138
      modelPos = nextModelPos;
 
139
      return nested.nextLine();
 
140
    }
 
141
    buf.append(model.substring(modelPos, breakPos));
 
142
    if (nextModelPos == model.length()) {
 
143
      done = true;
 
144
      buf.append(suffix);
 
145
    }
 
146
    modelPos = nextModelPos;
 
147
    return buf.toString();
 
148
  }
 
149
 
 
150
  private static boolean isSingleGroup(String model) {
 
151
    int length = model.length();
 
152
    if (length == 0)
 
153
      return false;
 
154
    int i = 0;
 
155
    if (model.charAt(0) == '|')
 
156
      i++;
 
157
    if (model.charAt(i) != '(')
 
158
      return false;
 
159
    loop:
 
160
    while (length > i) {
 
161
      switch (model.charAt(length - 1)) {
 
162
      case '*': case '+': case '?': case ',': case '|': case ')':
 
163
        length--;
 
164
        break;
 
165
      default:
 
166
        break loop;
 
167
      }
 
168
    }
 
169
    int level = 0;
 
170
    for (++i; i < length; i++)
 
171
      switch (model.charAt(i)) {
 
172
      case '(':
 
173
        level++;
 
174
        break;
 
175
      case ')':
 
176
        if (level == 0)
 
177
          return false;
 
178
        level--;
 
179
        break;
 
180
      }
 
181
    return true;
 
182
  }
 
183
 
 
184
  static public void main(String[] args) throws NumberFormatException {
 
185
    for (ModelBreaker breaker = new ModelBreaker(args[0], args[1], args[2], Integer.parseInt(args[3]));
 
186
         breaker.hasNextLine();)
 
187
      System.err.println(breaker.nextLine());
 
188
  }
 
189
}