thanks Joel!
Now that it works and my small test case is ok I want to raise u some
concerns about this new handy coming stuff which is "ClientBundle".
Here my case. I have many resources files (.properties) that I'd want to use
in a (pretty big) application. The Idea is to take advantage of the new
capabilities of ClientBundle :
- InlineProperties (for small files) and ExternalResources (for big files)
- eval() to speed up the fetching operation with JSon
ClientBundle is really nice to agregate Inline and External resources. The
problem is related to the fact that the developer has to deal with a lot of
async boilerplate code to fetch every single file.
So, I'm trying to figure out how I could save time and make it happen with
kind of patterns. let's take a central registry that would fetch all those
files in background, populate a dictionnary and notify an Async callback
when the things are done. This way :
onModuleLoad(...) {
RegistryProperties.load(new AsyncCallback<Void>() {
public void onFailure(Throwable caught) {
}
public void onSuccess(Void result) {
String myValue =
RegistryProperties.getProperties().get("myKey");
// We can use now any value/key pair
}
});
}
All the files would be asynchrously (or inlinely) fetched and tuning the
load method would "divide" the fetch operation in several chunks. A kind of
file "composition".
I have succeed in implementing this pattern but to be honest I have to make
some tricks to the current ClientBundle implementation.
1) it is not possible to have an "abstract" bundle. In my case, all the
boilerplate code is made within the subclass
2) properties are handled like dumb raw text which is very annoying because
each property has to be splitted out to get a Map. This operation is very
time consuming.
Wouldn't it be possible to store natively a well known properties file
(key=value \n key2=value2) as a JSon stream which would make the eval()->Map
more "natural" ?
3) the current eval() implementation raises an error on Chrome
4) ClientBundle holds dependencies with "new" classes (JSSourceWriter or
something like that) that don't exist in the current trunk
Here is my RegistryProperties impl :
public abstract class RegistryProperties implements ClientBundle {
private Map<String, String> map = new HashMap<String, String>();
private static RegistryProperties INSTANCE = null;
private AsyncCallback<Void> clientCB = null;
// Number of files to fetch (can be generated)
private int nbfiles = 4;
// the developer has to create those lines
@Source("message1.properties")
public abstract ExternalTextResource firstFile();
@Source("message2.properties")
public abstract ExternalTextResource secondFile();
@Source("message3.properties")
public abstract ExternalTextResource thirdFile();
@Source("message4.properties")
public abstract TextResource fourthFile();
// All the code below can be generated
public static final RegistryProperties create() {
if (INSTANCE == null)
INSTANCE = GWT.create(RegistryProperties.class);
return INSTANCE;
}
public Map<String, String> getProperties() {
return map;
}
ResourceCallback<TextResource> baseCallback = new
ResourceCallback<TextResource>() {
@Override
public void onError(ResourceException e) {
clientCB.onFailure(new Throwable(e.getMessage()) {
});
}
@Override
public void onSuccess(TextResource resource) {
stringToMap(resource.getText());
// When all files are fetched notity the client, can be part of
IncrementalCommand
if (0 == --nbfiles)
clientCB.onSuccess(null);
}
};
public Map stringToMap(String resource) {
final Map<String, String> m = new HashMap<String, String>();
JsArrayString tokens = split(resource, "\r\n");
for (int i = 0; i < tokens.length(); i++) {
m.put(nativeSplit(tokens.get(i), "=").get(0),
nativeSplit(tokens.get(i), "=")
.get(1));
}
map.putAll(m);
return m;
}
// This method appears to be less time-consuming than String.split() for
big strings
private native JsArrayString nativeSplit(String s, String pattern)/*-{
var reg=new RegExp(pattern);
var ar=s.split(reg);
return ar;
}-*/;
public static void load(AsyncCallback<Void> clientCB) throws Exception {
create();
clientCB = clientCB ;
INSTANCE.firstFile().getText(INSTANCE.baseCallback);
INSTANCE.secondFile().getText(INSTANCE.baseCallback);
INSTANCE.thirdFile().getText(INSTANCE.baseCallback);
}
Not sure, but I think Bob is in charge of ClientBundle, my questions are the
following :
- Is it possible to make abstract classes candidates for ClientBundle ?
- Is it possible to create a new ExternalTextResource which would be more
properties-oriented ? (ExternalPropertiesTextResource?)
To finish on this topic, there are some interesting patterns that one can
imagine with the duo CodeSpliting and ClientBundle. If we can create a big
file containing only inline resources, we can also split this big file in
many chunks with code splitting and mimic kind of ExternalResourceText....
Any thought?
Sami
On Thu, Apr 23, 2009 at 7:17 PM, Joel Webber <[email protected]> wrote:
> Sami,
> Looks like you might have some stale files around. WindowImplSafari was
> removed a while back (I think I had the same thing happen on my machine at
> one point).
>
> Hope that helps,
> joel.
>
>
> On Thu, Apr 23, 2009 at 1:13 PM, Sami Jaber <[email protected]> wrote:
>
>> I have tried to compile the trunk and I faced many issues (SvnInfo.java
>> has to be patched with --xml to get things to work)
>> After building the dist in 5273 revision, I get those errors in the log :
>>
>> Loading an instance of module 'ClientBundleTest'
>> Refreshing module from source
>> Validating newly compiled units
>> Removing units with errors
>> Errors in
>> 'jar:file:/C:/gwthack/trunk/build/dist/gwt-windows-1.6.r5273/gwt-user.jar!/com/google/gwt/user/client/impl/WindowImplSafari.java'
>> Line 23: The method getClientHeight() of type
>> WindowImplSafari must override or implement a supertype method
>> Line 34: The method getScrollLeft() of type
>> WindowImplSafari must override or implement a supertype method
>> Line 39: The method getScrollTop() of type WindowImplSafari
>> must override or implement a supertype method
>> Errors in
>> 'jar:file:/C:/gwthack/trunk/build/dist/gwt-windows-1.6.r5273/gwt-user.jar!/com/google/gwt/user/client/ListenerWrapper.java'
>> Line 78: The method onEventPreview(Event) in the type
>> EventPreview is not applicable for the arguments (NativeEvent)
>> Errors in
>> 'jar:file:/C:/gwthack/trunk/build/dist/gwt-windows-1.6.r5273/gwt-user.jar!/com/google/gwt/user/client/impl/WindowImplOpera.java'
>> Line 42: The method getClientHeight() of type
>> WindowImplOpera must override or implement a supertype method
>> Line 47: The method getClientWidth() of type
>> WindowImplOpera must override or implement a supertype method
>>
>> any idea ?
>>
>> Sami
>>
>>
>>
>
> >
>
--~--~---------~--~----~------------~-------~--~----~
http://groups.google.com/group/Google-Web-Toolkit-Contributors
-~----------~----~----~----~------~----~------~--~---