# HG changeset patch # User Jaroslav Tulach # Date 1378740870 -7200 # Node ID 37ad459579bcfcea3d7ad2b678ca2a4f92fc922f # Parent 3ee4ec9577bc3d9cdbfda8a9d9ddeff5c369ca7a Rewritting the archetype to be simpler and more easily modifiable to one's needs diff -r 3ee4ec9577bc -r 37ad459579bc ko/archetype-test/src/test/java/org/apidesign/bck2brwsr/ko/archetype/test/VerifyArchetypeTest.java --- a/ko/archetype-test/src/test/java/org/apidesign/bck2brwsr/ko/archetype/test/VerifyArchetypeTest.java Mon Sep 09 15:26:12 2013 +0200 +++ b/ko/archetype-test/src/test/java/org/apidesign/bck2brwsr/ko/archetype/test/VerifyArchetypeTest.java Mon Sep 09 17:34:30 2013 +0200 @@ -88,7 +88,6 @@ ZipFile zf = new ZipFile(zip); assertNotNull(zf.getEntry("public_html/index.html"), "index.html found"); - assertNotNull(zf.getEntry("public_html/twitterExample.css"), "css file found"); } diff -r 3ee4ec9577bc -r 37ad459579bc ko/archetype/src/main/resources/META-INF/maven/archetype-metadata.xml --- a/ko/archetype/src/main/resources/META-INF/maven/archetype-metadata.xml Mon Sep 09 15:26:12 2013 +0200 +++ b/ko/archetype/src/main/resources/META-INF/maven/archetype-metadata.xml Mon Sep 09 17:34:30 2013 +0200 @@ -26,8 +26,8 @@ **/*.java - - src/main/resources + + src/main/webapp/pages **/*.xhtml **/*.html diff -r 3ee4ec9577bc -r 37ad459579bc ko/archetype/src/main/resources/archetype-resources/pom.xml --- a/ko/archetype/src/main/resources/archetype-resources/pom.xml Mon Sep 09 15:26:12 2013 +0200 +++ b/ko/archetype/src/main/resources/archetype-resources/pom.xml Mon Sep 09 17:34:30 2013 +0200 @@ -42,7 +42,7 @@ ${project.version} ${project.version} MINIMAL - \${package.replace('.','/')}/index.html + pages/index.html @@ -58,8 +58,9 @@ - \${brwsr.startpage} - \${brwsr} + \${basedir}/src/main/webapp/ + ${brwsr.startpage} + ${brwsr} diff -r 3ee4ec9577bc -r 37ad459579bc ko/archetype/src/main/resources/archetype-resources/src/main/assembly/bck2brwsr.xml --- a/ko/archetype/src/main/resources/archetype-resources/src/main/assembly/bck2brwsr.xml Mon Sep 09 15:26:12 2013 +0200 +++ b/ko/archetype/src/main/resources/archetype-resources/src/main/assembly/bck2brwsr.xml Mon Sep 09 17:34:30 2013 +0200 @@ -29,6 +29,10 @@ / + + src/main/webapp/pages + / + diff -r 3ee4ec9577bc -r 37ad459579bc ko/archetype/src/main/resources/archetype-resources/src/main/assembly/fxbrwsr.xml --- a/ko/archetype/src/main/resources/archetype-resources/src/main/assembly/fxbrwsr.xml Mon Sep 09 15:26:12 2013 +0200 +++ b/ko/archetype/src/main/resources/archetype-resources/src/main/assembly/fxbrwsr.xml Mon Sep 09 17:34:30 2013 +0200 @@ -20,4 +20,13 @@ / + + + src/main/webapp/ + / + + pages/** + + + \ No newline at end of file diff -r 3ee4ec9577bc -r 37ad459579bc ko/archetype/src/main/resources/archetype-resources/src/main/java/DataModel.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/ko/archetype/src/main/resources/archetype-resources/src/main/java/DataModel.java Mon Sep 09 17:34:30 2013 +0200 @@ -0,0 +1,31 @@ +package ${package}; + +import net.java.html.json.ComputedProperty; +import net.java.html.json.Function; +import net.java.html.json.Model; +import net.java.html.json.Property; + +/** Model annotation generates class Data with + * one message property, boolean property and read only words property + */ +@Model(className = "Data", properties = { + @Property(name = "message", type = String.class), + @Property(name = "on", type = boolean.class) +}) +final class DataModel { + @ComputedProperty static java.util.List words(String message) { + String[] arr = new String[6]; + String[] words = message == null ? new String[0] : message.split(" ", 6); + for (int i = 0; i < 6; i++) { + arr[i] = words.length > i ? words[i] : "!"; + } + return java.util.Arrays.asList(arr); + } + + @Function static void turnOn(Data model) { + model.setOn(true); + } + @Function static void turnOff(Data model) { + model.setOn(false); + } +} diff -r 3ee4ec9577bc -r 37ad459579bc ko/archetype/src/main/resources/archetype-resources/src/main/java/Main.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/ko/archetype/src/main/resources/archetype-resources/src/main/java/Main.java Mon Sep 09 17:34:30 2013 +0200 @@ -0,0 +1,15 @@ +package ${package}; + +public final class Main { + private Main() { + } + + /** + * Called when the page is ready. + */ + static { + Data d = new Data(); + d.setMessage("Hello World from HTML and Java!"); + d.applyBindings(); + } +} diff -r 3ee4ec9577bc -r 37ad459579bc ko/archetype/src/main/resources/archetype-resources/src/main/java/TwitterClient.java --- a/ko/archetype/src/main/resources/archetype-resources/src/main/java/TwitterClient.java Mon Sep 09 15:26:12 2013 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,178 +0,0 @@ -package ${package}; - -import java.util.Arrays; -import java.util.List; -import net.java.html.json.ComputedProperty; -import net.java.html.json.Function; -import net.java.html.json.Model; -import net.java.html.json.OnPropertyChange; -import net.java.html.json.OnReceive; -import net.java.html.json.Property; - -@Model(className="TwitterModel", properties={ - @Property(name="savedLists", type=Tweeters.class, array = true), - @Property(name="activeTweetersName", type=String.class), - @Property(name="activeTweeters", type=String.class, array = true), - @Property(name="userNameToAdd", type=String.class), - @Property(name="loading", type=boolean.class), - @Property(name="currentTweets", type=Tweet.class, array = true) -}) -public class TwitterClient { - @Model(className = "Tweeters", properties = { - @Property(name="name", type = String.class), - @Property(name="userNames", type = String.class, array = true) - }) - static class Twttrs { - } - @Model(className = "Tweet", properties = { - @Property(name = "from_user", type = String.class), - @Property(name = "from_user_id", type = int.class), - @Property(name = "profile_image_url", type = String.class), - @Property(name = "text", type = String.class), - @Property(name = "created_at", type = String.class), - }) - static final class Twt { - @ComputedProperty static String html(String text) { - StringBuilder sb = new StringBuilder(320); - for (int pos = 0;;) { - int http = text.indexOf("http", pos); - if (http == -1) { - sb.append(text.substring(pos)); - return sb.toString(); - } - int spc = text.indexOf(' ', http); - if (spc == -1) { - spc = text.length(); - } - sb.append(text.substring(pos, http)); - String url = text.substring(http, spc); - sb.append("").append(url).append(""); - pos = spc; - } - } - - @ComputedProperty static String userUrl(String from_user) { - return "http://twitter.com/" + from_user; - } - } - @Model(className = "TwitterQuery", properties = { - @Property(array = true, name = "results", type = Twt.class) - }) - public static final class TwttrQr { - } - - @OnReceive(url="{root}/search.json?{query}&callback={me}", jsonp="me") - static void queryTweets(TwitterModel page, TwitterQuery q) { - page.getCurrentTweets().clear(); - page.getCurrentTweets().addAll(q.getResults()); - page.setLoading(false); - } - - @OnPropertyChange("activeTweetersName") - static void changeTweetersList(TwitterModel model) { - Tweeters people = findByName(model.getSavedLists(), model.getActiveTweetersName()); - model.getActiveTweeters().clear(); - model.getActiveTweeters().addAll(people.getUserNames()); - } - - @OnPropertyChange({ "activeTweeters", "activeTweetersCount" }) - static void refreshTweets(TwitterModel model) { - StringBuilder sb = new StringBuilder(); - sb.append("rpp=25&q="); - String sep = ""; - for (String p : model.getActiveTweeters()) { - sb.append(sep); - sb.append("from:"); - sb.append(p); - sep = " OR "; - } - model.setLoading(true); - model.queryTweets("http://search.twitter.com", sb.toString()); - } - - static { - final TwitterModel model = new TwitterModel(); - final List svdLst = model.getSavedLists(); - svdLst.add(newTweeters("API Design", "JaroslavTulach")); - svdLst.add(newTweeters("Celebrities", "JohnCleese", "MCHammer", "StephenFry", "algore", "StevenSanderson")); - svdLst.add(newTweeters("Microsoft people", "BillGates", "shanselman", "ScottGu")); - svdLst.add(newTweeters("NetBeans", "GeertjanW","monacotoni", "NetBeans", "petrjiricka")); - svdLst.add(newTweeters("Tech pundits", "Scobleizer", "LeoLaporte", "techcrunch", "BoingBoing", "timoreilly", "codinghorror")); - - model.setActiveTweetersName("NetBeans"); - - model.applyBindings(); - } - - @ComputedProperty - static boolean hasUnsavedChanges(List activeTweeters, List savedLists, String activeTweetersName) { - Tweeters tw = findByName(savedLists, activeTweetersName); - if (activeTweeters == null) { - return false; - } - return !tw.getUserNames().equals(activeTweeters); - } - - @ComputedProperty - static int activeTweetersCount(List activeTweeters) { - return activeTweeters.size(); - } - - @ComputedProperty - static boolean userNameToAddIsValid( - String userNameToAdd, String activeTweetersName, List savedLists, List activeTweeters - ) { - return userNameToAdd != null && - userNameToAdd.matches("[a-zA-Z0-9_]{1,15}") && - !activeTweeters.contains(userNameToAdd); - } - - @Function - static void deleteList(TwitterModel model) { - final List sl = model.getSavedLists(); - sl.remove(findByName(sl, model.getActiveTweetersName())); - if (sl.isEmpty()) { - final Tweeters t = new Tweeters(); - t.setName("New"); - sl.add(t); - } - model.setActiveTweetersName(sl.get(0).getName()); - } - - @Function - static void saveChanges(TwitterModel model) { - Tweeters t = findByName(model.getSavedLists(), model.getActiveTweetersName()); - int indx = model.getSavedLists().indexOf(t); - if (indx != -1) { - t.setName(model.getActiveTweetersName()); - t.getUserNames().clear(); - t.getUserNames().addAll(model.getActiveTweeters()); - } - } - - @Function - static void addUser(TwitterModel model) { - String n = model.getUserNameToAdd(); - model.getActiveTweeters().add(n); - } - @Function - static void removeUser(String data, TwitterModel model) { - model.getActiveTweeters().remove(data); - } - - private static Tweeters findByName(List list, String name) { - for (Tweeters l : list) { - if (l.getName() != null && l.getName().equals(name)) { - return l; - } - } - return list.isEmpty() ? new Tweeters() : list.get(0); - } - - private static Tweeters newTweeters(String listName, String... userNames) { - Tweeters t = new Tweeters(); - t.setName(listName); - t.getUserNames().addAll(Arrays.asList(userNames)); - return t; - } -} diff -r 3ee4ec9577bc -r 37ad459579bc ko/archetype/src/main/resources/archetype-resources/src/main/resources/index.html --- a/ko/archetype/src/main/resources/archetype-resources/src/main/resources/index.html Mon Sep 09 15:26:12 2013 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,90 +0,0 @@ - - - - - - - - Bck2Brwsr's Twitter - - - - - - - -

Bck2Brwsr's Twitter

- -

- This code is based on original - knockout.js - Twitter example and - uses almost unmodified HTML page. It just changes the model. The model - is written in Java language with the help of - - Knockout/Java binding library - . The Java source code has about 180 lines and seems more - dense and shorter than the original JavaScript model. -

-

- The project has two profiles. Either it executes in real Java virtual - machine and renders using JavaFX's WebView (use fxbrwsr profile - - the default). It can also run directly in a browser via - Bck2Brwsr virtual machine - (use bck2brwsr profile). -

- -
-
-
- - - -
- -

Currently viewing user(s):

-
-
    -
  • - -
    -
  • -
-
- -
- - - -
-
-
-
Loading...
- - - - - -
- - -
-
-
-
- - - - - - - diff -r 3ee4ec9577bc -r 37ad459579bc ko/archetype/src/main/resources/archetype-resources/src/main/resources/twitterExample.css --- a/ko/archetype/src/main/resources/archetype-resources/src/main/resources/twitterExample.css Mon Sep 09 15:26:12 2013 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,32 +0,0 @@ -/* - Copied from knockout.js Twitter example: - http://knockoutjs.com/examples/twitter.html -*/ - -.configuration, .tweets, .tweets td { font-family: Verdana; font-size: 13px; } -.configuration { background-color: #DEDEDE; border: 2px solid gray; float:left; height: 40em; width: 40%; padding: 0.5em; border-right-width:0; } -.tweets { width: 55%; border: 2px solid gray; height: 40em; overflow: scroll; overflow-x: hidden; background-color: Black; color: White; padding: 0.5em; position: relative; } -.tweets table { border-width: 0;} -.tweets tr { vertical-align: top; } -.tweets td { padding: 0.4em 0.3em 1em 0.4em; border-width: 0; } -.tweets img { width: 4em; } -.tweetInfo { color: Gray; font-size: 0.9em; } -.twitterUser { color: #77AAFF; text-decoration: none; font-size: 1.1em; font-weight: bold; } -input.invalid { border: 1px solid red !important; background-color: #FFAAAA !important; } - -.listChooser select, .listChooser button { vertical-align:top; } -.listChooser select { width: 60%; font-size:1.2em; height:1.4em; } -.listChooser button { width: 19%; height:1.68em; float:right; } - -.currentUsers { height: 28em; overflow-y: auto; overflow-x: hidden; } -.currentUsers button { float: right; height: 2.5em; margin: 0.1em; padding-left: 1em; padding-right: 1em; } -.currentUsers ul, .configuration li { list-style: none; margin: 0; padding: 0 } -.currentUsers li { height: 2.4em; font-size: 1.2em; background-color: #A7D0E3; border: 1px solid gray; margin-bottom: 0.3em; -webkit-border-radius: 5px; -moz-border-radius: 5px; -webkit-box-shadow: 0 0.2em 0.5em gray; -moz-box-shadow: 0 0.2em 0.5em gray; } -.currentUsers li div { padding: 0.6em; } -.currentUsers li:hover { background-color: #EEC; } - -.configuration form label { width: 25%; display: inline-block; text-align:right; overflow: hidden; } -.configuration form input { width:40%; font-size: 1.3em; border:1px solid silver; background-color: White; padding: 0.1em; } -.configuration form button { width: 20%; margin-left: 0.3em; height: 2em; } - -.loadingIndicator { position: absolute; top: 0.1em; left: 0.1em; font: 0.8em Arial; background-color: #229; color: White; padding: 0.2em 0.5em 0.2em 0.5em; } diff -r 3ee4ec9577bc -r 37ad459579bc ko/archetype/src/main/resources/archetype-resources/src/main/webapp/pages/index.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/ko/archetype/src/main/resources/archetype-resources/src/main/webapp/pages/index.html Mon Sep 09 17:34:30 2013 +0200 @@ -0,0 +1,63 @@ + + + + + + + + + + +

Words Demo

+ +
+ + + +
+ + + +
+ + + + diff -r 3ee4ec9577bc -r 37ad459579bc ko/archetype/src/main/resources/archetype-resources/src/test/java/DataModelTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/ko/archetype/src/main/resources/archetype-resources/src/test/java/DataModelTest.java Mon Sep 09 17:34:30 2013 +0200 @@ -0,0 +1,16 @@ +package ${package}; + +import static org.testng.Assert.*; +import org.testng.annotations.Test; + +public class DataModelTest { + @Test public void areHelloWorldTwoWords() { + Data model = new Data(); + model.setMessage("Hello World!"); + + java.util.List arr = model.getWords(); + assertEquals(arr.size(), 6, "Six words always"); + assertEquals("Hello", arr.get(0), "Hello is the first word"); + assertEquals("World!", arr.get(1), "World is the second word"); + } +} diff -r 3ee4ec9577bc -r 37ad459579bc ko/archetype/src/main/resources/archetype-resources/src/test/java/TwitterClientTest.java --- a/ko/archetype/src/main/resources/archetype-resources/src/test/java/TwitterClientTest.java Mon Sep 09 15:26:12 2013 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,50 +0,0 @@ -package ${package}; - -import java.util.List; -import net.java.html.BrwsrCtx; -import net.java.html.json.Models; -import static org.testng.Assert.*; -import org.testng.annotations.BeforeMethod; -import org.testng.annotations.Test; - -/** We can unit test the TwitterModel smoothly. - */ -public class TwitterClientTest { - private TwitterModel model; - - - @BeforeMethod - public void initModel() { - model = Models.bind(new TwitterModel(), BrwsrCtx.EMPTY); - } - - @Test public void testIsValidToAdd() { - model.setUserNameToAdd("Joe"); - Tweeters t = Models.bind(new Tweeters(), BrwsrCtx.EMPTY); - t.setName("test"); - model.getSavedLists().add(t); - model.setActiveTweetersName("test"); - - assertTrue(model.isUserNameToAddIsValid(), "Joe is OK"); - TwitterClient.addUser(model); - assertFalse(model.isUserNameToAddIsValid(), "Can't add Joe for the 2nd time"); - assertEquals(t.getUserNames().size(), 0, "Original tweeters list remains empty"); - - List mod = model.getActiveTweeters(); - assertTrue(model.isHasUnsavedChanges(), "We have modifications"); - assertEquals(mod.size(), 1, "One element in the list"); - assertEquals(mod.get(0), "Joe", "Its name is Joe"); - - assertSame(model.getActiveTweeters(), mod, "Editing list is the modified one"); - - TwitterClient.saveChanges(model); - assertFalse(model.isHasUnsavedChanges(), "Does not have anything to save"); - - assertSame(model.getActiveTweeters(), mod, "Still editing the old modified one"); - } - - @Test public void httpAtTheEnd() { - String res = TwitterClient.Twt.html("Ahoj http://kuk"); - assertEquals(res, "Ahoj http://kuk"); - } -} diff -r 3ee4ec9577bc -r 37ad459579bc ko/archetype/src/main/resources/archetype-resources/src/test/java/TwitterProtocolTest.java --- a/ko/archetype/src/main/resources/archetype-resources/src/test/java/TwitterProtocolTest.java Mon Sep 09 15:26:12 2013 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,73 +0,0 @@ -package ${package}; - -import org.apidesign.bck2brwsr.vmtest.BrwsrTest; -import org.apidesign.bck2brwsr.vmtest.Http; -import org.apidesign.bck2brwsr.vmtest.VMTest; -import org.testng.annotations.Factory; - -public class TwitterProtocolTest { - private TwitterModel page; - @Http(@Http.Resource( - path = "/search.json", - mimeType = "application/json", - parameters = {"callback"}, - content = "$0({\"completed_in\":0.04,\"max_id\":320055706885689344,\"max_id_str\"" - + ":\"320055706885689344\",\"page\":1,\"query\":\"from%3AJaroslavTulach\",\"refresh_url\":" - + "\"?since_id=320055706885689344&q=from%3AJaroslavTulach\"," - + "\"results\":[{\"created_at\":\"Fri, 05 Apr 2013 06:10:01 +0000\"," - + "\"from_user\":\"JaroslavTulach\",\"from_user_id\":420944648,\"from_user_id_str\":" - + "\"420944648\",\"from_user_name\":\"Jaroslav Tulach\",\"geo\":null,\"id\":320055706885689344," - + "\"id_str\":\"320055706885689344\",\"iso_language_code\":\"en\",\"metadata\":{\"result_type\":" - + "\"recent\"},\"profile_image_url\":\"http:\\/\\/a0.twimg.com\\/profile_images\\/1656828312\\/jst_normal.gif\"," - + "\"profile_image_url_https\":\"https:\\/\\/si0.twimg.com\\/profile_images\\/1656828312\\/jst_normal.gif\"," - + "\"source\":\"<a href="http:\\/\\/twitter.com\\/">web<\\/a>\",\"text\":" - + "\"@tom_enebo Amzng! Not that I would like #ruby, but I am really glad you guys stabilized the plugin + " - + "made it work in #netbeans 7.3! Gd wrk.\",\"to_user\":\"tom_enebo\",\"to_user_id\":14498747," - + "\"to_user_id_str\":\"14498747\",\"to_user_name\":\"tom_enebo\",\"in_reply_to_status_id\":319832359509839872," - + "\"in_reply_to_status_id_str\":\"319832359509839872\"},{\"created_at\":\"Thu, 04 Apr 2013 07:33:06 +0000\"," - + "\"from_user\":\"JaroslavTulach\",\"from_user_id\":420944648,\"from_user_id_str\":" - + "\"420944648\",\"from_user_name\":\"Jaroslav Tulach\",\"geo\":null,\"id\":319714227088678913," - + "\"id_str\":\"319714227088678913\",\"iso_language_code\":\"en\",\"metadata\":{\"result_type\":" - + "\"recent\"},\"profile_image_url\":\"http:\\/\\/a0.twimg.com\\/profile_images\\/1656828312\\/jst_normal.gif\"," - + "\"profile_image_url_https\":\"https:\\/\\/si0.twimg.com\\/profile_images\\/1656828312\\/jst_normal.gif\"," - + "\"source\":\"<a href="http:\\/\\/twitter.com\\/">web<\\/a>\",\"text\":" - + "\"RT @drkrab: At #erlangfactory @joerl: Frameworks grow in complexity until nobody can use them.\"}," - + "{\"created_at\":\"Tue, 02 Apr 2013 07:44:34 +0000\",\"from_user\":\"JaroslavTulach\"," - + "\"from_user_id\":420944648,\"from_user_id_str\":\"420944648\",\"from_user_name\":\"Jaroslav Tulach\"," - + "\"geo\":null,\"id\":318992336145248256,\"id_str\":\"318992336145248256\",\"iso_language_code\":\"en\"," - + "\"metadata\":{\"result_type\":\"recent\"},\"profile_image_url\":" - + "\"http:\\/\\/a0.twimg.com\\/profile_images\\/1656828312\\/jst_normal.gif\"," - + "\"profile_image_url_https\":\"https:\\/\\/si0.twimg.com\\/profile_images\\/1656828312\\/jst_normal.gif\"," - + "\"source\":\"<a href="http:\\/\\/twitter.com\\/">web<\\/a>\",\"text\":" - + "\"Twitter renamed to twttr http:\\/\\/t.co\\/tqaN4T1xlZ - good, I don't have to rename #bck2brwsr!\"}," - + "{\"created_at\":\"Sun, 31 Mar 2013 03:52:04 +0000\",\"from_user\":\"JaroslavTulach\",\"from_user_id\":420944648," - + "\"from_user_id_str\":\"420944648\",\"from_user_name\":\"Jaroslav Tulach\",\"geo\":null," - + "\"id\":318209051223789568,\"id_str\":\"318209051223789568\",\"iso_language_code\":\"en\",\"metadata\":" - + "{\"result_type\":\"recent\"},\"profile_image_url\":" - + "\"http:\\/\\/a0.twimg.com\\/profile_images\\/1656828312\\/jst_normal.gif\"," - + "\"profile_image_url_https\":\"https:\\/\\/si0.twimg.com\\/profile_images\\/1656828312\\/jst_normal.gif\"," - + "\"source\":\"<a href="http:\\/\\/twitter.com\\/">web<\\/a>\",\"text\":" - + "\"Math proofs without words. Ingenious: http:\\/\\/t.co\\/sz7yVbfpGw\"}],\"results_per_page\":100," - + "\"since_id\":0,\"since_id_str\":\"0\"})" - )) - @BrwsrTest public void readFromTwttr() throws InterruptedException { - if (page == null) { - page = new TwitterModel(); - page.applyBindings(); - page.queryTweets("", "q=xyz"); - } - - if (page.getCurrentTweets().isEmpty()) { - throw new InterruptedException(); - } - - assert 4 == page.getCurrentTweets().size() : "Four tweets: " + page.getCurrentTweets(); - - String firstDate = page.getCurrentTweets().get(0).getCreated_at(); - assert "Fri, 05 Apr 2013 06:10:01 +0000".equals(firstDate) : "Date is OK: " + firstDate; - } - - @Factory public static Object[] create() { - return VMTest.create(TwitterProtocolTest.class); - } -} diff -r 3ee4ec9577bc -r 37ad459579bc launcher/api/src/main/java/org/apidesign/bck2brwsr/launcher/Launcher.java --- a/launcher/api/src/main/java/org/apidesign/bck2brwsr/launcher/Launcher.java Mon Sep 09 15:26:12 2013 +0200 +++ b/launcher/api/src/main/java/org/apidesign/bck2brwsr/launcher/Launcher.java Mon Sep 09 17:34:30 2013 +0200 @@ -148,7 +148,7 @@ if (classes != null) { l.addClassLoader(classes); } - l.showDirectory(directory, startpage); + l.showDirectory(directory, startpage, classes != null); return (Closeable) l; } @@ -172,7 +172,7 @@ return Launcher.class.getClassLoader().loadClass(cn); } - void showDirectory(File directory, String startpage) throws IOException { + void showDirectory(File directory, String startpage, boolean addClasses) throws IOException { throw new UnsupportedOperationException(); } diff -r 3ee4ec9577bc -r 37ad459579bc launcher/fx/src/main/java/org/apidesign/bck2brwsr/launcher/BaseHTTPLauncher.java --- a/launcher/fx/src/main/java/org/apidesign/bck2brwsr/launcher/BaseHTTPLauncher.java Mon Sep 09 15:26:12 2013 +0200 +++ b/launcher/fx/src/main/java/org/apidesign/bck2brwsr/launcher/BaseHTTPLauncher.java Mon Sep 09 17:34:30 2013 +0200 @@ -125,7 +125,7 @@ } } - void showDirectory(File dir, String startpage) throws IOException { + void showDirectory(File dir, String startpage, boolean addClasses) throws IOException { if (!startpage.startsWith("/")) { startpage = "/" + startpage; } @@ -134,7 +134,7 @@ if (last >= 0) { prefix = startpage.substring(0, last); } - HttpServer s = initServer(dir.getPath(), false, prefix); + HttpServer s = initServer(dir.getPath(), addClasses, prefix); try { launchServerAndBrwsr(s, startpage); } catch (Exception ex) { diff -r 3ee4ec9577bc -r 37ad459579bc launcher/fx/src/main/java/org/apidesign/bck2brwsr/launcher/FXBrwsrLauncher.java --- a/launcher/fx/src/main/java/org/apidesign/bck2brwsr/launcher/FXBrwsrLauncher.java Mon Sep 09 15:26:12 2013 +0200 +++ b/launcher/fx/src/main/java/org/apidesign/bck2brwsr/launcher/FXBrwsrLauncher.java Mon Sep 09 17:34:30 2013 +0200 @@ -17,11 +17,14 @@ */ package org.apidesign.bck2brwsr.launcher; +import java.io.File; import org.apidesign.bck2brwsr.launcher.fximpl.FXBrwsr; import java.io.IOException; import java.io.InputStream; import java.lang.reflect.Method; +import java.net.JarURLConnection; import java.net.URI; +import java.net.URISyntaxException; import java.net.URL; import java.net.URLClassLoader; import java.util.ArrayList; @@ -34,6 +37,7 @@ import java.util.logging.Logger; import javafx.application.Platform; import org.apidesign.bck2brwsr.launcher.fximpl.JVMBridge; +import org.openide.util.Exceptions; /** * @@ -116,15 +120,29 @@ String startPage = null; final ClassLoader cl = FXBrwsrLauncher.class.getClassLoader(); - startPage = findStartPage(cl, startPage); + URL[] manifestURL = { null }; + startPage = findStartPage(cl, startPage, manifestURL); if (startPage == null) { throw new NullPointerException("Can't find StartPage tag in manifests!"); } - Launcher.showURL("fxbrwsr", cl, startPage); + File dir = new File("."); + if (manifestURL[0].getProtocol().equals("jar")) { + try { + dir = new File( + ((JarURLConnection)manifestURL[0].openConnection()).getJarFileURL().toURI() + ).getParentFile(); + } catch (URISyntaxException ex) { + LOG.log(Level.WARNING, "Can't find root directory", ex); + } + } + + Launcher.showDir("fxbrwsr", dir, cl, startPage); } - private static String findStartPage(final ClassLoader cl, String startPage) throws IOException { + private static String findStartPage( + final ClassLoader cl, String startPage, URL[] startURL + ) throws IOException { Enumeration en = cl.getResources("META-INF/MANIFEST.MF"); while (en.hasMoreElements()) { URL url = en.nextElement(); @@ -139,6 +157,9 @@ String sp = mf.getMainAttributes().getValue("StartPage"); if (sp != null) { startPage = sp; + if (startURL != null) { + startURL[0] = url; + } break; } }