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.*;
|
import java.util.*;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This represents a Helma skin, i.e. a template created from JavaScript. It uses the request path array
|
* This represents a Helma skin, i.e. a template created from containing Macro tags
|
||||||
* from the RequestEvaluator object to resolve dynamic tokens.
|
* 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 {
|
public class Skin {
|
||||||
|
|
||||||
Object[] parts;
|
Macro[] parts;
|
||||||
Application app;
|
Application app;
|
||||||
String source;
|
char[] source;
|
||||||
|
int sourceLength;
|
||||||
HashSet sandbox;
|
HashSet sandbox;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -37,48 +39,55 @@ public class Skin {
|
||||||
public Skin (String content, Application app, HashSet sandbox) {
|
public Skin (String content, Application app, HashSet sandbox) {
|
||||||
this.app = app;
|
this.app = app;
|
||||||
this.sandbox = sandbox;
|
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
|
* Parse a skin object from source text
|
||||||
*/
|
*/
|
||||||
public void parse (String content) {
|
private void parse () {
|
||||||
|
|
||||||
this.source = content;
|
|
||||||
ArrayList partBuffer = new ArrayList ();
|
ArrayList partBuffer = new ArrayList ();
|
||||||
int l = content.length ();
|
|
||||||
char cnt[] = new char[l];
|
|
||||||
content.getChars (0, l, cnt, 0);
|
|
||||||
|
|
||||||
int lastIdx = 0;
|
int start = 0;
|
||||||
for (int i = 0; i < l-1; i++) {
|
for (int i = 0; i < sourceLength-1; i++) {
|
||||||
if (cnt[i] == '<' && cnt[i+1] == '%') {
|
if (source[i] == '<' && source[i+1] == '%') {
|
||||||
|
// found macro start tag
|
||||||
int j = i+2;
|
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++;
|
j++;
|
||||||
}
|
}
|
||||||
if (j > i+2) {
|
if (j > i+2) {
|
||||||
if (i - lastIdx > 0)
|
partBuffer.add (new Macro (i, j+2));
|
||||||
partBuffer.add (new String (cnt, lastIdx, i - lastIdx));
|
start = j+2;
|
||||||
String macrotext = new String (cnt, i+2, (j-i)-2);
|
|
||||||
partBuffer.add (new Macro (macrotext));
|
|
||||||
lastIdx = j+2;
|
|
||||||
}
|
}
|
||||||
i = j+1;
|
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
|
* Get the raw source text this skin was parsed from
|
||||||
*/
|
*/
|
||||||
public String getSource () {
|
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 {
|
public void render (RequestEvaluator reval, Object thisObject, HashMap paramObject) throws RedirectException {
|
||||||
|
|
||||||
if (parts == null)
|
if (parts == null)
|
||||||
return;
|
reval.res.writeCharArray (source, 0, sourceLength);
|
||||||
|
|
||||||
|
int written = 0;
|
||||||
for (int i=0; i<parts.length; i++) {
|
for (int i=0; i<parts.length; i++) {
|
||||||
if (parts[i] instanceof Macro)
|
if (parts[i].start > written)
|
||||||
((Macro) parts[i]).render (reval, thisObject, paramObject);
|
reval.res.writeCharArray (source, written, parts[i].start-written);
|
||||||
else
|
parts[i].render (reval, thisObject, paramObject);
|
||||||
reval.res.write (parts[i]);
|
written = parts[i].end;
|
||||||
}
|
}
|
||||||
|
if (written < sourceLength)
|
||||||
|
reval.res.writeCharArray (source, written, sourceLength-written);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -128,56 +140,56 @@ public class Skin {
|
||||||
|
|
||||||
class Macro {
|
class Macro {
|
||||||
|
|
||||||
|
int start, end;
|
||||||
String handler;
|
String handler;
|
||||||
String name;
|
String name;
|
||||||
String fullname;
|
String fullname;
|
||||||
HashMap parameters;
|
HashMap parameters;
|
||||||
|
|
||||||
public Macro (String str) {
|
public Macro (int start, int end) {
|
||||||
|
|
||||||
|
this.start = start;
|
||||||
|
this.end = end;
|
||||||
|
|
||||||
parameters = new HashMap ();
|
parameters = new HashMap ();
|
||||||
|
|
||||||
int l = str.length ();
|
|
||||||
char cnt[] = new char[l];
|
|
||||||
str.getChars (0, l, cnt, 0);
|
|
||||||
|
|
||||||
int state = HANDLER;
|
int state = HANDLER;
|
||||||
boolean escape = false;
|
boolean escape = false;
|
||||||
char quotechar = '\u0000';
|
char quotechar = '\u0000';
|
||||||
String lastParamName = null;
|
String lastParamName = null;
|
||||||
StringBuffer b = new StringBuffer();
|
StringBuffer b = new StringBuffer();
|
||||||
|
|
||||||
for (int i=0; i<l; i++) {
|
for (int i=start+2; i<end-2; i++) {
|
||||||
switch (cnt[i]) {
|
switch (source[i]) {
|
||||||
case '.':
|
case '.':
|
||||||
if (state == HANDLER) {
|
if (state == HANDLER) {
|
||||||
handler = b.toString ().trim();
|
handler = b.toString ().trim();
|
||||||
b.setLength (0);
|
b.setLength (0);
|
||||||
state = MACRO;
|
state = MACRO;
|
||||||
} else
|
} else
|
||||||
b.append (cnt[i]);
|
b.append (source[i]);
|
||||||
break;
|
break;
|
||||||
case '\\':
|
case '\\':
|
||||||
if (escape)
|
if (escape)
|
||||||
b.append (cnt[i]);
|
b.append (source[i]);
|
||||||
escape = !escape;
|
escape = !escape;
|
||||||
break;
|
break;
|
||||||
case '"':
|
case '"':
|
||||||
case '\'':
|
case '\'':
|
||||||
if (!escape && state == PARAMVALUE) {
|
if (!escape && state == PARAMVALUE) {
|
||||||
if (quotechar == cnt[i]) {
|
if (quotechar == source[i]) {
|
||||||
parameters.put (lastParamName, b.toString());
|
parameters.put (lastParamName, b.toString());
|
||||||
lastParamName = null;
|
lastParamName = null;
|
||||||
b.setLength (0);
|
b.setLength (0);
|
||||||
state = PARAMNAME;
|
state = PARAMNAME;
|
||||||
quotechar = '\u0000';
|
quotechar = '\u0000';
|
||||||
} else if (quotechar == '\u0000') {
|
} else if (quotechar == '\u0000') {
|
||||||
quotechar = cnt[i];
|
quotechar = source[i];
|
||||||
b.setLength (0);
|
b.setLength (0);
|
||||||
} else
|
} else
|
||||||
b.append (cnt[i]);
|
b.append (source[i]);
|
||||||
} else
|
} else
|
||||||
b.append (cnt[i]);
|
b.append (source[i]);
|
||||||
escape = false;
|
escape = false;
|
||||||
break;
|
break;
|
||||||
case ' ':
|
case ' ':
|
||||||
|
@ -195,7 +207,7 @@ public class Skin {
|
||||||
b.setLength (0);
|
b.setLength (0);
|
||||||
state = PARAMNAME;
|
state = PARAMNAME;
|
||||||
} else if (state == PARAMVALUE)
|
} else if (state == PARAMVALUE)
|
||||||
b.append (cnt[i]);
|
b.append (source[i]);
|
||||||
else
|
else
|
||||||
b.setLength (0);
|
b.setLength (0);
|
||||||
break;
|
break;
|
||||||
|
@ -205,10 +217,10 @@ public class Skin {
|
||||||
b.setLength (0);
|
b.setLength (0);
|
||||||
state = PARAMVALUE;
|
state = PARAMVALUE;
|
||||||
} else
|
} else
|
||||||
b.append (cnt[i]);
|
b.append (source[i]);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
b.append (cnt[i]);
|
b.append (source[i]);
|
||||||
escape = false;
|
escape = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -415,7 +427,6 @@ public class Skin {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue