Pretty much streamlined Skin parsing and rendering,
trying to reduce the number of objects created.
This commit is contained in:
parent
e618c5c8a2
commit
1085f83d02
1 changed files with 60 additions and 49 deletions
|
@ -13,15 +13,17 @@ import java.io.*;
|
|||
import java.util.*;
|
||||
|
||||
/**
|
||||
* This represents a Helma skin, i.e. a template created from JavaScript. It uses the request path array
|
||||
* from the RequestEvaluator object to resolve dynamic tokens.
|
||||
* This represents a Helma skin, i.e. a template created from containing Macro tags
|
||||
* that will be dynamically evaluated.. It uses the request path array
|
||||
* from the RequestEvaluator object to resolve Macro handlers by type name.
|
||||
*/
|
||||
|
||||
public class Skin {
|
||||
|
||||
Object[] parts;
|
||||
Macro[] parts;
|
||||
Application app;
|
||||
String source;
|
||||
char[] source;
|
||||
int sourceLength;
|
||||
HashSet sandbox;
|
||||
|
||||
/**
|
||||
|
@ -37,48 +39,55 @@ public class Skin {
|
|||
public Skin (String content, Application app, HashSet sandbox) {
|
||||
this.app = app;
|
||||
this.sandbox = sandbox;
|
||||
parse (content);
|
||||
source = content.toCharArray ();
|
||||
sourceLength = source.length;
|
||||
parse ();
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a skin without any restrictions on the macros from a char array.
|
||||
*/
|
||||
public Skin (char[] content, int length, Application app) {
|
||||
this.app = app;
|
||||
this.sandbox = null;
|
||||
this.source = content;
|
||||
this.sourceLength = length;
|
||||
parse ();
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse a skin object from source text
|
||||
*/
|
||||
public void parse (String content) {
|
||||
private void parse () {
|
||||
|
||||
this.source = content;
|
||||
ArrayList partBuffer = new ArrayList ();
|
||||
int l = content.length ();
|
||||
char cnt[] = new char[l];
|
||||
content.getChars (0, l, cnt, 0);
|
||||
|
||||
int lastIdx = 0;
|
||||
for (int i = 0; i < l-1; i++) {
|
||||
if (cnt[i] == '<' && cnt[i+1] == '%') {
|
||||
int start = 0;
|
||||
for (int i = 0; i < sourceLength-1; i++) {
|
||||
if (source[i] == '<' && source[i+1] == '%') {
|
||||
// found macro start tag
|
||||
int j = i+2;
|
||||
while (j < l-1 && (cnt[j] != '%' || cnt[j+1] != '>')) {
|
||||
// search macr end tag
|
||||
while (j < sourceLength-1 && (source[j] != '%' || source[j+1] != '>')) {
|
||||
j++;
|
||||
}
|
||||
if (j > i+2) {
|
||||
if (i - lastIdx > 0)
|
||||
partBuffer.add (new String (cnt, lastIdx, i - lastIdx));
|
||||
String macrotext = new String (cnt, i+2, (j-i)-2);
|
||||
partBuffer.add (new Macro (macrotext));
|
||||
lastIdx = j+2;
|
||||
partBuffer.add (new Macro (i, j+2));
|
||||
start = j+2;
|
||||
}
|
||||
i = j+1;
|
||||
}
|
||||
}
|
||||
if (lastIdx < l)
|
||||
partBuffer.add (new String (cnt, lastIdx, l - lastIdx));
|
||||
|
||||
parts = partBuffer.toArray ();
|
||||
parts = new Macro[partBuffer.size()];
|
||||
partBuffer.toArray (parts);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the raw source text this skin was parsed from
|
||||
*/
|
||||
public String getSource () {
|
||||
return source;
|
||||
return new String (source, 0, sourceLength);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -87,14 +96,17 @@ public class Skin {
|
|||
public void render (RequestEvaluator reval, Object thisObject, HashMap paramObject) throws RedirectException {
|
||||
|
||||
if (parts == null)
|
||||
return;
|
||||
reval.res.writeCharArray (source, 0, sourceLength);
|
||||
|
||||
int written = 0;
|
||||
for (int i=0; i<parts.length; i++) {
|
||||
if (parts[i] instanceof Macro)
|
||||
((Macro) parts[i]).render (reval, thisObject, paramObject);
|
||||
else
|
||||
reval.res.write (parts[i]);
|
||||
if (parts[i].start > written)
|
||||
reval.res.writeCharArray (source, written, parts[i].start-written);
|
||||
parts[i].render (reval, thisObject, paramObject);
|
||||
written = parts[i].end;
|
||||
}
|
||||
if (written < sourceLength)
|
||||
reval.res.writeCharArray (source, written, sourceLength-written);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -128,56 +140,56 @@ public class Skin {
|
|||
|
||||
class Macro {
|
||||
|
||||
int start, end;
|
||||
String handler;
|
||||
String name;
|
||||
String fullname;
|
||||
HashMap parameters;
|
||||
|
||||
public Macro (String str) {
|
||||
public Macro (int start, int end) {
|
||||
|
||||
this.start = start;
|
||||
this.end = end;
|
||||
|
||||
parameters = new HashMap ();
|
||||
|
||||
int l = str.length ();
|
||||
char cnt[] = new char[l];
|
||||
str.getChars (0, l, cnt, 0);
|
||||
|
||||
int state = HANDLER;
|
||||
boolean escape = false;
|
||||
char quotechar = '\u0000';
|
||||
String lastParamName = null;
|
||||
StringBuffer b = new StringBuffer();
|
||||
|
||||
for (int i=0; i<l; i++) {
|
||||
switch (cnt[i]) {
|
||||
for (int i=start+2; i<end-2; i++) {
|
||||
switch (source[i]) {
|
||||
case '.':
|
||||
if (state == HANDLER) {
|
||||
handler = b.toString ().trim();
|
||||
b.setLength (0);
|
||||
state = MACRO;
|
||||
} else
|
||||
b.append (cnt[i]);
|
||||
b.append (source[i]);
|
||||
break;
|
||||
case '\\':
|
||||
if (escape)
|
||||
b.append (cnt[i]);
|
||||
b.append (source[i]);
|
||||
escape = !escape;
|
||||
break;
|
||||
case '"':
|
||||
case '\'':
|
||||
if (!escape && state == PARAMVALUE) {
|
||||
if (quotechar == cnt[i]) {
|
||||
if (quotechar == source[i]) {
|
||||
parameters.put (lastParamName, b.toString());
|
||||
lastParamName = null;
|
||||
b.setLength (0);
|
||||
state = PARAMNAME;
|
||||
quotechar = '\u0000';
|
||||
} else if (quotechar == '\u0000') {
|
||||
quotechar = cnt[i];
|
||||
quotechar = source[i];
|
||||
b.setLength (0);
|
||||
} else
|
||||
b.append (cnt[i]);
|
||||
b.append (source[i]);
|
||||
} else
|
||||
b.append (cnt[i]);
|
||||
b.append (source[i]);
|
||||
escape = false;
|
||||
break;
|
||||
case ' ':
|
||||
|
@ -195,7 +207,7 @@ public class Skin {
|
|||
b.setLength (0);
|
||||
state = PARAMNAME;
|
||||
} else if (state == PARAMVALUE)
|
||||
b.append (cnt[i]);
|
||||
b.append (source[i]);
|
||||
else
|
||||
b.setLength (0);
|
||||
break;
|
||||
|
@ -205,10 +217,10 @@ public class Skin {
|
|||
b.setLength (0);
|
||||
state = PARAMVALUE;
|
||||
} else
|
||||
b.append (cnt[i]);
|
||||
b.append (source[i]);
|
||||
break;
|
||||
default:
|
||||
b.append (cnt[i]);
|
||||
b.append (source[i]);
|
||||
escape = false;
|
||||
}
|
||||
}
|
||||
|
@ -415,7 +427,6 @@ public class Skin {
|
|||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue