[jsword-devel] Flashcard build silliness

DM Smith dmsmith555 at yahoo.com
Mon Sep 13 17:52:43 MST 2004


Sorry for the delay in answering. Just got back from a weekend holiday.

Troy, I am going to be fairly complete. Probably much of this you have 
figured out by now or already knew. My goal in doing this is that 
FlashCards is your baby and I want you to have full knowledge of what I 
have done. So that you will feel fairly comfortable with the changes.

The CWClassLoader finds resources using a fairly sophisticated lookup 
mechanism so that you will not have to create your own.

Here is the basic history, design and implementation of CWClassLoader 
and ResourceUtil: (This should help to answer your question)
Java's basis mechanism for lookup is either explicit (i.e. I know where 
the file is so I construct a path name from what is known.) or implicit 
(i.e. use the class path to look for the file.) The latter mechanism was 
that if you called classObj.getResource(xyz), it had one of two 
behaviors. If the name began with a '/' the resource would be sought for 
along the classpath. If it did not it was looked for in the same 
directory as the definition of the class object.

Since the program could be installed anywhere, we initially supplied a 
shell script (bat file) that would start up the program. Relative to 
that directory, we had a resource directory where all resources were 
kept. The path of the resource directory was passed into the program and 
it was put on the classpath. With this we could either use explicit 
lookup or call getResource using '/'.

For JSword, the resources were initially being kept in files that had 
dotted names like files in packages:
E.g. org.crosswire.jsword.book.BibleInfo.properties
The purpose of this was to allow a developer to easily change the 
properties. It was also the place where the program maintained 
persistent performance data that was used for the progress meters.

When we went to WebStart, a couple of things happened. First, we could 
not write to the resource directory. So we had to have a different 
location. Second, since webstart requires all resources to be held in 
signed jars, the developer could not modify the resources. Third, we had 
no idea where WebStart would store the program, so we could not pass in 
the installation location. Fourth, we no longer had control over the 
classpath that was created and could not add an arbitrary directory 
location.

We had worked out a way that we could use getResource to find a 
resource, but now needed to also explicitly look for it in the file 
system as well. So we wrote code that first looked in ~/.jsword and then 
in the jars. This was all well and good, but when we went to 
internationalize the program, we had to treat the property files as 
ResourceBundles. And ResourceBundles always use a class loader to find 
resources. So we had to migrate the lookup to a ClassLoader and use it.

So, in a nutshell here is how it works. Lets say that you have a 
resource called lessonA.flash that is used by 
org.crosswire.flashcards.Reader. If CWClassLoader is used to find 
lessons/black/lessonA.flash via ResourceUtil.getResource(). It will look 
for the file in the following places with the following names:
First look for it relative to the package:
1) org.crosswire.flashcards.lessons.black.lessonA.flash in ~/.flashcards
2) org.crosswire.flashcards.lessons.black.lessonA.flash in a jar
Then look for it relative to the root of the classpath:
3) lessons.black.lessonA.flash in ~/.flashcards
4) lessons.black.lessonsA.flash in the a jar
Finally look for it as a file:
5)  lessons/black/lessonA.flash in ~/.flashcards
6) lessons/black/lessonA.flash in the jar

That is, it manages the lookup for you.

To have it look in ~/.flashcards the program needs to do the following: 
(Assume DIR_PROJECT is .flashcards)
            String path = System.getProperty("user.home") + 
File.separator + DIR_PROJECT; //$NON-NLS-1$
            URL home = new URL(FILE_PROTOCOL, null, path);
            CWClassLoader.setHome(home);

If two different programs (Quiz and Editor) work on the same location, 
then both programs need to have these three lines.

The twist that FlashCards has that is not present in JSword, it that 
JSword merely looks up a known resource, but FlashCards discovers what 
resources it has available. FlashCards then has the additional step of 
creating a map of discovered resources. When it discovers the resource 
it does not remember whether it was found in the filesystem or in the 
jar. It lets the ResourceUtil.getResource figure that out at that time.

So in looking at the code you will find that it looks for lessons thusly
It first digs into the jar to get lessons with getJarLessons. Since 
these are not located in org.crosswire.flashcards, a '/' is prefixed.
Then it looks in the file system with getHomeLessons.

As it gets the lessons, they are stored by their path. Then by their URL 
with the widget.

Now if one of these lessons is loaded into the Editor, it may have come 
from the jar or it may have come from the filesystem. It really does not 
matter. ResourceUtil.getResource will sort it out. When the file is 
written out, it will need to be saved in the filesystem. Any URLs that 
are remembered for the resource will have to be updated. (Right now each 
checkbox remembers the URL. If this were to change to being the path, 
then no place would need to be adjusted.)

So here are the changes I see that the program needs to have done to 
make it work with what it has:
1) Add CWClassLoader.setHome to EditorFrame so it will work in stand 
alone mode.
2) change the JFileChoosers to look in CWClassLoader.getHome() (i.e. 
line 213 in MainFrame, 45 and 62 in EditorFrame)
3) Store the path on the widget (i.e. a String and not an URL) and do 
the lookup for the URL when the lesson is loaded.

At this time, the program assumes that the lessons are in a subdirectory 
of a "lessons" directory. So some thought may want to be put into 
whether this is a good restriction or not. If so, the user really does 
not need to open a JFileChooser, they could either pick an existing 
lesson to edit or create one from scratch by naming the lesson set (e.g. 
black) and the lesson (e.g. lesson01vocab). The program would be 
responsible for converting this to a path and writing it to the file system.

If the user can write to any location then CWClassLoader would need to 
change setHome to setHomePath and each location would need to be stored 
in a persistent location so it could be remembered the next run.

I would also suggest a change to the setup screen, where the name of the 
lesson set is pickable (JComboBox or JList would do). When it is picked, 
then a list of lessons is populated. I suggest having a scrollable JList 
of the checkboxes.

The trick would be to have the JComboBox listen for the creation of new 
lesson sets and the lesson listing to update when they are added, 
deleted or renamed or reordered. I suggest the Observer pattern using a 
LessonEditEvent and a LessonEditEventListener.

As I "broke" the editing function, I would be willing to help in 
whatever way you wish.

Hope this helps,
    DM

Troy A. Griffitts wrote:

> Hey DM,
>     Been working on re-adding support for editing files into 
> flashcards and am trying to understand how things work.  Help me learn 
> about the need for the classloader extension.
>
>     Here is what I think the path might be for loading the lesson groups.
>
>     1. look on the resource path (basically, the flashcards.jar file) 
> for "lessons/<lesson_group>/*.flash
>     2. CWD "file:lessons/<lesson_group>/*.flash
>     3. CWD "jar:file:lessons/*.jar!/lessons/<lesson_group>/*.flash
>     4. HOME "file:${user.home}/.flashcards/lessons/ 
> <lesson_group>/*.flash
>     5. HOME "jar:file:${user.home}/.flashcards/lessons/ 
> *.jar!/lessons/<lesson_group>/*.flash
>
>     I was going to attempt to write this today with 2 functions which 
> could be called from the quizzer and the editor could use at least the 
> first when the path is chosen:
>
>     // called for each <lesson_group> found
>     public static void addLessonGroup(Map lessonGroups, URL url);
>
>     // called 5 times with above logic
>     public static Vector discoverLessonGroups(URL lessonsPath);
>
>
>     ...but thought it best to ask you for direction, as I still don't 
> understand the function of the class loader.
>
>     Thanks for your efforts and in advance for your guidance!
>
>         -Troy.
>
>
>
>
>
> DM Smith wrote:
>
>> For those that were following this thread. Troy, John and I took it 
>> the conversation offline to figure out the problem.
>> We have fixed the problem (which was that the jar did not have the 
>> image files needed for the editor).
>>
>> The program is available via webstart at www.crosswire.org/flashcards.
>>
>> John's addition to the program is the ability to run the editor from 
>> inside of the quizzer.
>>
>> Troy A. Griffitts wrote:
>>
>>> OK John,
>>>     Here's my latest discoveries.
>>>
>>>     If I build on the server with ant and jdk 1.5.0, I have the null 
>>> editor window, running on XP jdk 1.4.1.
>>>     If I build on the server with ant and jdk 1.4.2, I have the null 
>>> editor window, running on XP jdk 1.4.1.
>>>     If I build on the server with your build script and jdk 1.5.0, I 
>>> get 1.5.0 compile errors which have been fixed and committed, and 
>>> then I get:
>>>
>>> Exception in thread "main" java.lang.UnsupportedClassVersionError: 
>>> org/crosswire /flashcards/Quiz (Unsupported major.minor version 49.0)
>>>
>>>     which is probably expected from XP and jdk 1.4.1
>>>
>>>     If I build on the server with your build script and jdk 1.4.2 
>>> everything works on XP jdk 1.4.1.
>>>
>>>     Hope we can track this down.
>>>
>>>         -Troy.
>>>
>>> get On Thu, 9 Sep 2004, John Jacques wrote:
>>>
>>>> Troy,
>>>>
>>>> I don't get anything when I try to run the editor from the MainMenu
>>>> using webstart (Quiz does work).  All works well when I run from the
>>>> command line (on Linux):
>>>>
>>>>     $ java -jar flashcards.jar
>>>>
>>>> The Editor is the correct size etc.
>>>>
>>>> I almost have my local web server set up to allow me to use webstart.
>>>> The last remaining obsticle is signing the jar file!  I am trying as
>>>> recommended
>>>> (http://java.sun.com/j2se/1.4.2/docs/guide/jws/developersguide/development.html#signing) 
>>>> but haven't been able to obtain 'unrestricted access'...
>>>>
>>>> On Thu, 2004-09-09 at 12:20, Troy A. Griffitts wrote:
>>>>
>>>>> John,
>>>>>      We could try setting a size.  It's not necessarily a webstart
>>>>> issue.  I got that error I reported to you by running the produced 
>>>>> jar
>>>>> file on an XP box.  If you click on the webstart link from this page:
>>>>>
>>>>> http://crosswire.org/flashcards/
>>>>>
>>>>> does the edit choice work for you?
>>>>>
>>>>> I can grab the corner of the very small editor window and resize it
>>>>> larger, but there is nothing on the client area.
>>>>>
>>>>> If you'd really like the breathing marks to be entered before the 
>>>>> letters,
>>>>> the IM mechanism supports multiple keystroke for character entry.  
>>>>> This is
>>>>> used in the Michigan Claremont Hebrew keymap, if you'd like to see 
>>>>> how it
>>>>> works.  Actually, just reviewed HebrewMCIM.java and it looks really
>>>>> convoluted.  Sorry about that.
>>>>>
>>>>>      Thanks for your work!
>>>>>
>>>>>          -Troy.
>>>>>
>>>>>
>>>>>
>>>>> On Wed, 8 Sep 2004, John Jacques wrote:
>>>>>
>>>>>> Troy,
>>>>>>
>>>>>> The main difference I see is that MainFrame.java doesn't use
>>>>>> java.awt.Toolkit to determine the screen size as in Editor.java.  It
>>>>>> might be worth setting a screen size there...
>>>>>>
>>>>>> I'm glad my other changes didn't break anything!
>>>>>>
>>>>>> I'll try to set up webstart on a local webserver.  Looks like I 
>>>>>> would
>>>>>> just have to edit Flashcards.jnlp.  Is it that simple?
>>>>>>
>>>>>> On Wed, 2004-09-08 at 16:49, Troy A. Griffitts wrote:
>>>>>>
>>>>>>> John,
>>>>>>>      Thank you for your recent submissions.  I have updated the
>>>>>>> webstart installer to the latest code and the editor doesn't 
>>>>>>> seem to
>>>>>>> launch for me.  I get an error:
>>>>>>>   ERROR :
>>>>>>> org.crosswire.flashcards.EditorFrame[frame0,0,0,0x0,invalid,hidden,layo 
>>>>>>>
>>>>>>> ut=java.awt.BorderLayout,title=,resizable,normal,defaultCloseOperation=HIDE_ON_C 
>>>>>>>
>>>>>>> LOSE,rootPane=javax.swing.JRootPane[,0,0,0x0,invalid,layout=javax.swing.JRootPan 
>>>>>>>
>>>>>>> e$RootLayout,alignmentX=null,alignmentY=null,border=,flags=385,maximumSize=,mini 
>>>>>>>
>>>>>>> mumSize=,preferredSize=],rootPaneCheckingEnabled=true] :
>>>>>>> Thread[main,5,main]
>>>>>>> null
>>>>>>>
>>>>>>> and a very small windows (actually just the titlebar).
>>>>>>>
>>>>>>> Let me know if you have an idea what it might be.  Thank you.
>>>>>>>
>>>>>>>      -Troy.
>>>>>>>
>>>>>>>
>>>>>>> On Wed, 18 Aug 2004, John Jacques wrote:
>>>>>>>
>>>>>>>> Troy,
>>>>>>>>
>>>>>>>> I'm going to check in my changes to flashcards.  So far there 
>>>>>>>> are no
>>>>>>>> major changes, just minor fixes.
>>>>>>>>
>>>>>>>> If I want to make larger changes, should we branch?  Does the 
>>>>>>>> revision
>>>>>>>> (4 in this case) match up with other CrossWire software such as 
>>>>>>>> modedit
>>>>>>>> (which I believe is used elsewhere)?
>>>>>>>>
>>>>>>>> One last question, is there a mailing list, or any other forum, 
>>>>>>>> where
>>>>>>>> new ideas should be discussed before they are implemented?
>>>>>>>>
>>>>>>>> On Sun, 2004-08-15 at 03:23, Troy A. Griffitts wrote:
>>>>>>>>
>>>>>>>>> John,
>>>>>>>>>     We've recently changed servers and it has been keeping me 
>>>>>>>>> busy for the
>>>>>>>>> past few weeks.  We just put a new live SVN repository online at:
>>>>>>>>>
>>>>>>>>> https://crosswire.org/svn/flashcards/
>>>>>>>>>
>>>>>>>>> The repository permission is currently WORLD READ/WRITE.  If 
>>>>>>>>> you would
>>>>>>>>> like to commit your changes to the repository, you are welcome 
>>>>>>>>> to do so.
>>>>>>>>>   Not sure if you've had subversion experience.  If now, you 
>>>>>>>>> can find
>>>>>>>>> info and software at:
>>>>>>>>>
>>>>>>>>> http://subversion.tigris.org
>>>>>>>>>
>>>>>>>>> Thanks again for your willingness to help.
>>>>>>>>>
>>>>>>>>>     -Troy.
>>>>>>>>>
>>>>>>>>>
>>>>>>>>>
>>>>>>>>> John Jacques wrote:
>>>>>>>>>
>>>>>>>>>> Troy,
>>>>>>>>>>
>>>>>>>>>> I made the following changes.  Let me know if you keep any of 
>>>>>>>>>> them!
>>>>>>>>>> There are files named "Changes.eruditelite" in any directory 
>>>>>>>>>> I made
>>>>>>>>>> changes in that describe each change and the modified files.  
>>>>>>>>>> I have
>>>>>>>>>> also included the change files in this messages (see below).
>>>>>>>>>>
>>>>>>>>>> Are you using a revision control system?
>>>>>>>>>>
>>>>>>>>>> Also, what do you think of the following proposals:
>>>>>>>>>>
>>>>>>>>>>     1) Add a Quiz mode in which the user is presented with the
>>>>>>>>>>        vocabulary word only (not multiple choice) and then the
>>>>>>>>>>            answer (either time delayed or by pressing a 
>>>>>>>>>> button).  The
>>>>>>>>>>            user then indicates whether they knew the word or 
>>>>>>>>>> not.  The
>>>>>>>>>>            current mode (multiple choice) would still be 
>>>>>>>>>> available.
>>>>>>>>>>
>>>>>>>>>>     2) Cleanup ".flash" files when saving (eliminate unused
>>>>>>>>>>            entries, renumber etc.)
>>>>>>>>>>
>>>>>>>>>> ========== In the top directory:
>>>>>>>>>>
>>>>>>>>>> 1) Added GNUmakefile to speedup working from emacs/command line.
>>>>>>>>>> 2) Updated to the latest (on the website 22 July 2004) 
>>>>>>>>>> modedit.  This
>>>>>>>>>>    allowed me to enter text (classical greek) in Mandrake 10.0.
>>>>>>>>>> 3) Added MounceBasicsChapter04.flash (Vocabulary from Chapter 
>>>>>>>>>> 4 of
>>>>>>>>>>    Mounce's Basics of Biblical Greek).
>>>>>>>>>>
>>>>>>>>>> ========== In src/flash:
>>>>>>>>>>
>>>>>>>>>> 1) Changed tool tip for "Save" from "Help" to "Save"
>>>>>>>>>> (EditorFrame.java:102)
>>>>>>>>>> 2) Stopped displaying exception on startup when 
>>>>>>>>>> "NewLesson.flash"
>>>>>>>>>>    didn't exist.  (EidtorFrame.java:247)
>>>>>>>>>>
>>>>>>>>>> On Sat, 2004-07-17 at 16:37, Troy A. Griffitts wrote:
>>>>>>>>>>
>>>>>>>>>>> John,
>>>>>>>>>>>     Thanks for the offer.  We'd love any help you'd be 
>>>>>>>>>>> willing to
>>>>>>>>>>> volunteer.  That's how our open projects improve!  You'll 
>>>>>>>>>>> find the source
>>>>>>>>>>> in the same directory pointed to by the download link.  I 
>>>>>>>>>>> don't think we
>>>>>>>>>>> have an actual link to it yet.
>>>>>>>>>>>
>>>>>>>>>>>     We do have some c++/linux/handheld apps:
>>>>>>>>>>>     http://crosswire.org/qpsword/
>>>>>>>>>>>
>>>>>>>>>>>     And we'd love to see flashcards run on the Zaurus! :)  
>>>>>>>>>>> Or at least
>>>>>>>>>>> a client that reads the same lesson formats.
>>>>>>>>>>>
>>>>>>>>>>>     Thanks you again for your persistence to get our app to 
>>>>>>>>>>> work and
>>>>>>>>>>> willingness to help!
>>>>>>>>>>>
>>>>>>>>>>>     -Troy A. Griffitts
>>>>>>>>>>>
>>>>>>>>>>>
>>>>>>>>>>>
>>>>>>>>>>> On Sat, 17 Jul 2004, John Jacques wrote:
>>>>>>>>>>>
>>>>>>>>>>>
>>>>>>>>>>>> Troy,
>>>>>>>>>>>>
>>>>>>>>>>>> Thanks for the response!  The final sigma is " (double 
>>>>>>>>>>>> quote) and my
>>>>>>>>>>>> confusion about saving a new list was the pop-up hint for 
>>>>>>>>>>>> the save
>>>>>>>>>>>> button (which says "Help").  It all works now...
>>>>>>>>>>>>
>>>>>>>>>>>> If you are interested in programming help, let me know.  I 
>>>>>>>>>>>> am a
>>>>>>>>>>>> programmer (embedded Linux/Real Time) so most of my 
>>>>>>>>>>>> experience is OS
>>>>>>>>>>>> porting and device drivers but I have written a fair amount 
>>>>>>>>>>>> of Java
>>>>>>>>>>>> (~7,000 lines) including a Swing GUI.
>>>>>>>>>>>>
>>>>>>>>>>>> On Sat, 2004-07-17 at 07:02, Troy A. Griffitts wrote:
>>>>>>>>>>>>
>>>>>>>>>>>>> John, I believe that final sigma is the ' key.  Did you 
>>>>>>>>>>>>> type a filename
>>>>>>>>>>>>> in the filename box before you hit save?  I realize this 
>>>>>>>>>>>>> isn't an
>>>>>>>>>>>>> orthodox method for saving a new file, but it's a first 
>>>>>>>>>>>>> rev of the
>>>>>>>>>>>>> software.  Please let me know if this information hasn't 
>>>>>>>>>>>>> helped get you
>>>>>>>>>>>>> going.
>>>>>>>>>>>>>
>>>>>>>>>>>>>     -Troy A. Griffitts.
>>>>>>>>>>>>>
>>>>>>>>>>>>>
>>>>>>>>>>>>>
>>>>>>>>>>>>> John Jacques wrote:
>>>>>>>>>>>>>
>>>>>>>>>>>>>> First of all, thank you for a wonderful program!  
>>>>>>>>>>>>>> However, I can't seem
>>>>>>>>>>>>>> to get FlashEditor.jar to save any of the changes I make 
>>>>>>>>>>>>>> or let me enter
>>>>>>>>>>>>>> a sigma (the end of word sigma that is)...
>>>>>>>>>>>>>>
>>>>>>>>>>>>>> _______________________________________________
>>>>>>>>>>>>>> sword-support mailing list
>>>>>>>>>>>>>> sword-support at crosswire.org
>>>>>>>>>>>>>
>>>>>>>>>>>>>
>>>>>>>>>>>>>
>>>>>>>>>>>>>
>>>>>>>>>
>>>>>>>>
>>>>>>
>>>>
>>> _______________________________________________
>>> jsword-devel mailing list
>>> jsword-devel at crosswire.org
>>> http://www.crosswire.org/mailman/listinfo/jsword-devel
>>>
>>
>> _______________________________________________
>> jsword-devel mailing list
>> jsword-devel at crosswire.org
>> http://www.crosswire.org/mailman/listinfo/jsword-devel
>
>
> _______________________________________________
> jsword-devel mailing list
> jsword-devel at crosswire.org
> http://www.crosswire.org/mailman/listinfo/jsword-devel
>



More information about the jsword-devel mailing list