How to use MusicXmlParser in jFugue 5.0? - jfugue
I'm trying to parse a Staccato Pattern into MusicXml. However, it's not working, as the parsed MusicXml contains almost nothing. I don't know if it's due to something wrong with my Staccato string, or the MusicXmlParser.
Here's my code, including the Staccato string:
public class TestMusicXml {
public static void main(String[] args) {
Pattern p = new Pattern(
"#Score_Beginning I[PIANO] T100 TIME:6/4 KEY:AMIN #Variation_0 #Chord_0 A4/0.25 | F#5/0.25 F#5/0.25 A4/0.25 D5/0.25 D5/0.25 A4/0.25 | #Chord_1 G4/0.25 | Eb5/0.25 Eb5/0.25 G4/0.25 C5/0.25 C5/0.25 G4/0.25 | #Chord_2 F#5/0.25 | D6/0.25 D6/0.25 F#5/0.25 B4/0.25 B4/0.25 F#5/0.25 | #Chord_3 E5/0.25 | C#6/0.25 C#6/0.25 E5/0.25 A4/0.25 A4/0.25 #Variation_1 E5/0.25 | #Chord_0 A4/0.25 | F#5/0.25 F#5/0.25 A4/0.25 D5/0.25 D5/0.25 A4/0.25 | #Chord_1 G4/0.25 | Eb5/0.25 Eb5/0.25 G4/0.25 C5/0.25 C5/0.25 G4/0.25 | #Chord_2 F#5/0.25 | D6/0.25 D6/0.25 F#5/0.25 B4/0.25 B4/0.25 F#5/0.25 | #Chord_3 E5/0.25 | C#6/0.25 C#6/0.25 E5/0.25 A4/0.25 A4/0.25 #Variation_2 E5/0.25 | #Chord_0 A4/0.25 | F#5/0.25 F#5/0.25 A4/0.25 D5/0.25 D5/0.25 A4/0.25 | #Chord_1 G4/0.25 | Eb5/0.25 Eb5/0.25 G4/0.25 C5/0.25 C5/0.25 G4/0.25 | #Chord_2 F#5/0.25 | D6/0.25 D6/0.25 F#5/0.25 B4/0.25 B4/0.25 F#5/0.25 | #Chord_3 E5/0.25 | C#6/0.25 C#6/0.25 E5/0.25 A4/0.25 A4/0.25 #Variation_3 E5/0.25 | #Chord_0 A3/0.25 | F#4/0.25 F#4/0.25 A3/0.25 D5/0.25 D5/0.25 A3/0.25 | #Chord_1 G3/0.25 | Eb4/0.25 Eb4/0.25 G3/0.25 C5/0.25 C5/0.25 G3/0.25 | #Chord_2 F#4/0.25 | D5/0.25 D5/0.25 F#4/0.25 B4/0.25 B4/0.25 F#4/0.25 | #Chord_3 E4/0.25 | C#5/0.25 C#5/0.25 E4/0.25 A4/0.25 A4/0.25 #Variation_4 E4/0.25 | #Chord_0 A3/0.25 | F#4/0.25 F#4/0.25 A3/0.25 D5/0.25 D5/0.25 A3/0.25 | #Chord_1 G3/0.25 | Eb4/0.25 Eb4/0.25 G3/0.25 C5/0.25 C5/0.25 G3/0.25 | #Chord_2 F#4/0.25 | D5/0.25 D5/0.25 F#4/0.25 B4/0.25 B4/0.25 F#4/0.25 | #Chord_3 E4/0.25 | C#5/0.25 C#5/0.25 E4/0.25 A4/0.25 A4/0.25 #Variation_5 E4/0.25 | #Chord_0 A4/0.25 | F#5/0.25 F#5/0.25 A4/0.25 D5/0.25 D5/0.25 A4/0.25 | #Chord_1 G4/0.25 | Eb5/0.25 Eb5/0.25 G4/0.25 C5/0.25 C5/0.25 G4/0.25 | #Chord_2 F#5/0.25 | D6/0.25 D6/0.25 F#5/0.25 B4/0.25 B4/0.25 F#5/0.25 | #Chord_3 E5/0.25 | C#6/0.25 C#6/0.25 E5/0.25 A4/0.25 A4/0.25 E5/0.25 |");
StaccatoParser parser = new StaccatoParser();
MusicXmlParserListener listener = new MusicXmlParserListener();
parser.addParserListener(listener);
DevLog.debug("parsing: " + p);
parser.parse(p);
String musicXmlStr = listener.getMusicXMLString();
DevLog.debug("writing music xml: " + musicXmlStr);
}
}
Here is the output:
2017-07-16 05:36:16.649 1 D [SysProp] song.devlog.printDateTimeInSystemOut=DefaultVal: true, SetVal : null
2017-07-16 05:36:16.649 1 D [SysProp] song.devlog.printNothingInSystemOut=DefaultVal: false, SetVal : null
2017-07-16 05:36:16.649 1 D [SysProp] issac.logLevel=DefaultVal: -S-T-D-I-W-E-, SetVal : null
2017-07-16 05:36:16.626 1 D parsing: #Score_Beginning I[PIANO] T100 TIME:6/4 KEY:AMIN #Variation_0 #Chord_0 A4/0.25 | F#5/0.25 F#5/0.25 A4/0.25 D5/0.25 D5/0.25 A4/0.25 | #Chord_1 G4/0.25 | Eb5/0.25 Eb5/0.25 G4/0.25 C5/0.25 C5/0.25 G4/0.25 | #Chord_2 F#5/0.25 | D6/0.25 D6/0.25 F#5/0.25 B4/0.25 B4/0.25 F#5/0.25 | #Chord_3 E5/0.25 | C#6/0.25 C#6/0.25 E5/0.25 A4/0.25 A4/0.25 #Variation_1 E5/0.25 | #Chord_0 A4/0.25 | F#5/0.25 F#5/0.25 A4/0.25 D5/0.25 D5/0.25 A4/0.25 | #Chord_1 G4/0.25 | Eb5/0.25 Eb5/0.25 G4/0.25 C5/0.25 C5/0.25 G4/0.25 | #Chord_2 F#5/0.25 | D6/0.25 D6/0.25 F#5/0.25 B4/0.25 B4/0.25 F#5/0.25 | #Chord_3 E5/0.25 | C#6/0.25 C#6/0.25 E5/0.25 A4/0.25 A4/0.25 #Variation_2 E5/0.25 | #Chord_0 A4/0.25 | F#5/0.25 F#5/0.25 A4/0.25 D5/0.25 D5/0.25 A4/0.25 | #Chord_1 G4/0.25 | Eb5/0.25 Eb5/0.25 G4/0.25 C5/0.25 C5/0.25 G4/0.25 | #Chord_2 F#5/0.25 | D6/0.25 D6/0.25 F#5/0.25 B4/0.25 B4/0.25 F#5/0.25 | #Chord_3 E5/0.25 | C#6/0.25 C#6/0.25 E5/0.25 A4/0.25 A4/0.25 #Variation_3 E5/0.25 | #Chord_0 A3/0.25 | F#4/0.25 F#4/0.25 A3/0.25 D5/0.25 D5/0.25 A3/0.25 | #Chord_1 G3/0.25 | Eb4/0.25 Eb4/0.25 G3/0.25 C5/0.25 C5/0.25 G3/0.25 | #Chord_2 F#4/0.25 | D5/0.25 D5/0.25 F#4/0.25 B4/0.25 B4/0.25 F#4/0.25 | #Chord_3 E4/0.25 | C#5/0.25 C#5/0.25 E4/0.25 A4/0.25 A4/0.25 #Variation_4 E4/0.25 | #Chord_0 A3/0.25 | F#4/0.25 F#4/0.25 A3/0.25 D5/0.25 D5/0.25 A3/0.25 | #Chord_1 G3/0.25 | Eb4/0.25 Eb4/0.25 G3/0.25 C5/0.25 C5/0.25 G3/0.25 | #Chord_2 F#4/0.25 | D5/0.25 D5/0.25 F#4/0.25 B4/0.25 B4/0.25 F#4/0.25 | #Chord_3 E4/0.25 | C#5/0.25 C#5/0.25 E4/0.25 A4/0.25 A4/0.25 #Variation_5 E4/0.25 | #Chord_0 A4/0.25 | F#5/0.25 F#5/0.25 A4/0.25 D5/0.25 D5/0.25 A4/0.25 | #Chord_1 G4/0.25 | Eb5/0.25 Eb5/0.25 G4/0.25 C5/0.25 C5/0.25 G4/0.25 | #Chord_2 F#5/0.25 | D6/0.25 D6/0.25 F#5/0.25 B4/0.25 B4/0.25 F#5/0.25 | #Chord_3 E5/0.25 | C#6/0.25 C#6/0.25 E5/0.25 A4/0.25 A4/0.25 E5/0.25 |
2017-07-16 05:36:16.674 1 D writing music xml:
JFugue MusicXMLRenderer
So the parsed musicXml result is:
<?xml version="1.0"?>
<!DOCTYPE score-partwise PUBLIC "-//Recordare//DTD MusicXML 1.1 Partwise//EN" "http://www.musicxml.org/dtds/partwise.dtd">
<score-partwise><identification><creator type="software">JFugue MusicXMLRenderer</creator></identification><part-list /></score-partwise>
All my notes are gone. What am I missing?
Thanks in advance.
It's buried too far in JFugue's Download page to be immediately obvious, but: "Please note that there is no current implementation for MusicXmlParserListener. JFugue still needs: a MusicXmlParserListener updated for JFugue 5.0, more thorough tests for MusicXMLParser, ..."
(I'll work on making that more obvious for others who download the code).
The MusicXML functionality in JFugue is contributed by volunteers, and there have been some gaps in updating the code for the most recent version of MusicXML and the most recent version of JFugue.
Related
Find references to files, recursively
In a project where XML/JS/Java files can contain references to other such files, I'd like to be able to have a quick overview of what has to be carefully checked, when one file has been updated. So, it means I need to eventually have a look at all files referencing the modified one, and all files referencing files which refer to the modified one, etc. (recursively on matched files). For one level, it's quite simple: grep -E -l -o --include=*.{xml,js,java} -r "$FILE" . | xargs -n 1 basename But how can I automate that to match (grand-(grand-))parents? And how can that be, maybe, made more readable? For example, with a tree structure? For example, if the file that interests me is called modified.js... show-referring-files-to modified.js ... I could wish such an output: some-file-with-ref-to-modified.xml |__ a-file-referring-to-some-file-with-ref-to-modified.js another-one-with-ref-to-modified.xml |__ a-file-referring-to-another-one-with-ref-to-modified.js |__ a-grand-parent-file-having-ref-to-ref-file.xml |__ another-file-referring-to-another-one-with-ref-to-modified.js or any other output (even flat) which allows for quickly checking which files are potentially impacted by a change. UPDATE -- Results of current proposed answer: ahmsff.js |__ahmsff.xml | |__ahmsd.js | | |__ahmsd.xml | | | |__ahmst.xml | | | | |__BESH.java | |__ahru.js | | |__ahru.xml | | | |__ahrut.xml | | | | |__ashrba.js | | | | | |__ashrba.xml | | | | | | |__STR.java | | |__ahrufrp.xml | | | |__ahru.js | | | | |__ahru.xml | | | | | |__ahrut.xml | | | | | | |__ashrba.js | | | | | | | |__ashrba.xml | | | | | | | | |__STR.java | | | | |__ahrufrp.xml | | | | | |__ahru.js | | | | | | |__ahru.xml | | | | | | | |__ahrut.xml | | | | | | | | |__ashrba.js | | | | | | | | | |__ashrba.xml | | | | | | | | | | |__STR.java | | | | | | |__ahrufrp.xml (...)
I'd use a shell function (for the recursion) inside an shell script: Assuming the filenames are unique have no characters that need escaping in them: File: /usr/local/bin/show-referring-files-to #!/bin/sh get_references() { grep -F -l --include=*.{xml,js,java} -r "$1" . | grep -v "$3" | while read -r subfile; do #read each line of the grep result into the variable subfile subfile="$(basename "$subfile")" echo "$2""$subfile" get_references "$subfile" ' '"$2" "$3"'\|'"$subfile" done } while test $# -gt 0; do #loop so more than one file can be given as argument to this script echo "$1" get_references "$1" '|__' "$1" shift done There still are lots of performance enhancements possible. Edit: Added $3 to prevent infinite-loop.
lftp upload files inside different folders
I need to upload files in different folders with same name, recursively to a remote folder. Here a example. Local |-app1-1 | |-src | |-img | |-static | |-app1-2 <------Upload from this | |-file1-1 | |-file1-2 |-app2-1 | |-src | |-img | |-static | |-app2-2 <------Upload from this | |-file2-1 | |-file2-2 Here the remote result I need. Remote Result |-folder1 |-folder2 |-folder3 |-static | |-app1-2 <------Upload from this | | |-file1-1 | | |-file1-2 | | | |-app2-2 <------Upload from this | | |-file2-1 | | |-file2-1 I have testing with scripts like this: - > lftp -e "mirror --include ^static/ --exclude ^\.git.* -eRv $CI_PROJECT_DIR Remote Result/static; quit;" sftp://$CREDENTIALS But this generate a output not desired: Remote Result |-folder1 |-folder2 |-folder3 |-static | |-app1-1 <------Upload from this | | |-static | | |-app1-2 | | |-file1 | | |-file2 ...... (Same other folder)
Filter lines containing date between a range in csv file in shell
I am new to shell and need to filter files from temp.csv using a range of date. Content of csv is below. ABHA_BSC,11DPM12-1-7-C1,10/2/2016 21:00,10176244118,61948776719,Juniper_GBE_ABHA_BSC-1-7-C1_JIZAN-1-7-C1_JIZ1AH1-01 | (SOUTHERN_ABHA_ABH0027-MX480-1 TO SOUTHERN_JIZAN_JIZ0005-MX104-1),1GbE ABHA_BSC,11DPM12-1-7-C1,10/2/2016 21:15,8277521465,54472178563,Juniper_GBE_ABHA_BSC-1-7-C1_JIZAN-1-7-C1_JIZ1AH1-01 | (SOUTHERN_ABHA_ABH0027-MX480-1 TO SOUTHERN_JIZAN_JIZ0005-MX104-1),1GbE ABHA_BSC,11DPM12-1-7-C1,10/2/2016 21:30,8105902217,53136518653,Juniper_GBE_ABHA_BSC-1-7-C1_JIZAN-1-7-C1_JIZ1AH1-01 | (SOUTHERN_ABHA_ABH0027-MX480-1 TO SOUTHERN_JIZAN_JIZ0005-MX104-1),1GbE ABHA_BSC,11DPM12-1-7-C1,10/2/2016 21:45,8213431962,53183143647,Juniper_GBE_ABHA_BSC-1-7-C1_JIZAN-1-7-C1_JIZ1AH1-01 | (SOUTHERN_ABHA_ABH0027-MX480-1 TO SOUTHERN_JIZAN_JIZ0005-MX104-1),1GbE ABHA_BSC,11DPM12-1-7-C1,10/2/2016 22:00,7951867805,53442712809,Juniper_GBE_ABHA_BSC-1-7-C1_JIZAN-1-7-C1_JIZ1AH1-01 | (SOUTHERN_ABHA_ABH0027-MX480-1 TO SOUTHERN_JIZAN_JIZ0005-MX104-1),1GbE ABHA_BSC,11DPM12-1-7-C1,10/2/2016 22:15,7741104157,52587797047,Juniper_GBE_ABHA_BSC-1-7-C1_JIZAN-1-7-C1_JIZ1AH1-01 | (SOUTHERN_ABHA_ABH0027-MX480-1 TO SOUTHERN_JIZAN_JIZ0005-MX104-1),1GbE ABHA_BSC,11DPM12-1-7-C1,10/2/2016 22:30,7393727032,52228344686,Juniper_GBE_ABHA_BSC-1-7-C1_JIZAN-1-7-C1_JIZ1AH1-01 | (SOUTHERN_ABHA_ABH0027-MX480-1 TO SOUTHERN_JIZAN_JIZ0005-MX104-1),1GbE ABHA_BSC,11DPM12-1-7-C1,10/2/2016 22:45,7035552805,49033988457,Juniper_GBE_ABHA_BSC-1-7-C1_JIZAN-1-7-C1_JIZ1AH1-01 | (SOUTHERN_ABHA_ABH0027-MX480-1 TO SOUTHERN_JIZAN_JIZ0005-MX104-1),1GbE ABHA_BSC,11DPM12-1-7-C1,10/2/2016 23:00,6956202883,46914504782,Juniper_GBE_ABHA_BSC-1-7-C1_JIZAN-1-7-C1_JIZ1AH1-01 | (SOUTHERN_ABHA_ABH0027-MX480-1 TO SOUTHERN_JIZAN_JIZ0005-MX104-1),1GbE ABHA_BSC,11DPM12-1-7-C1,10/2/2016 23:15,6623893225,42756482355,Juniper_GBE_ABHA_BSC-1-7-C1_JIZAN-1-7-C1_JIZ1AH1-01 | (SOUTHERN_ABHA_ABH0027-MX480-1 TO SOUTHERN_JIZAN_JIZ0005-MX104-1),1GbE ABHA_BSC,11DPM12-1-7-C1,10/2/2016 23:30,6781639211,44625787536,Juniper_GBE_ABHA_BSC-1-7-C1_JIZAN-1-7-C1_JIZ1AH1-01 | (SOUTHERN_ABHA_ABH0027-MX480-1 TO SOUTHERN_JIZAN_JIZ0005-MX104-1),1GbE ABHA_BSC,11DPM12-1-7-C1,10/2/2016 23:45,6586403766,41882620412,Juniper_GBE_ABHA_BSC-1-7-C1_JIZAN-1-7-C1_JIZ1AH1-01 | (SOUTHERN_ABHA_ABH0027-MX480-1 TO SOUTHERN_JIZAN_JIZ0005-MX104-1),1GbE ABHA_BSC,11DPM12-1-7-C11,10/2/2016 21:00,11895958325,75139993057,Juniper_GBE_ABHA_BSC-1-7-C11_JIZAN-1-7-C11_JIZ1AH1-03 | (SOUTHERN_ABHA_ABH0027-MX480-2 TO SOUTHERN_JIZAN_JIZ0005-MX104-2),1GbE ABHA_BSC,11DPM12-1-7-C11,10/2/2016 21:15,11040804077,70012701080,Juniper_GBE_ABHA_BSC-1-7-C11_JIZAN-1-7-C11_JIZ1AH1-03 | (SOUTHERN_ABHA_ABH0027-MX480-2 TO SOUTHERN_JIZAN_JIZ0005-MX104-2),1GbE ABHA_BSC,11DPM12-1-7-C11,10/2/2016 21:30,10647919562,69074001433,Juniper_GBE_ABHA_BSC-1-7-C11_JIZAN-1-7-C11_JIZ1AH1-03 | (SOUTHERN_ABHA_ABH0027-MX480-2 TO SOUTHERN_JIZAN_JIZ0005-MX104-2),1GbE ABHA_BSC,11DPM12-1-7-C11,10/2/2016 21:45,10365456912,68592543420,Juniper_GBE_ABHA_BSC-1-7-C11_JIZAN-1-7-C11_JIZ1AH1-03 | (SOUTHERN_ABHA_ABH0027-MX480-2 TO SOUTHERN_JIZAN_JIZ0005-MX104-2),1GbE ABHA_BSC,11DPM12-1-7-C11,10/2/2016 22:00,10217309244,66630665557,Juniper_GBE_ABHA_BSC-1-7-C11_JIZAN-1-7-C11_JIZ1AH1-03 | (SOUTHERN_ABHA_ABH0027-MX480-2 TO SOUTHERN_JIZAN_JIZ0005-MX104-2),1GbE ABHA_BSC,11DPM12-1-7-C11,10/2/2016 22:15,10354867964,66097450466,Juniper_GBE_ABHA_BSC-1-7-C11_JIZAN-1-7-C11_JIZ1AH1-03 | (SOUTHERN_ABHA_ABH0027-MX480-2 TO SOUTHERN_JIZAN_JIZ0005-MX104-2),1GbE ABHA_BSC,11DPM12-1-7-C11,10/2/2016 22:30,10584852507,65666291858,Juniper_GBE_ABHA_BSC-1-7-C11_JIZAN-1-7-C11_JIZ1AH1-03 | (SOUTHERN_ABHA_ABH0027-MX480-2 TO SOUTHERN_JIZAN_JIZ0005-MX104-2),1GbE ABHA_BSC,11DPM12-1-7-C11,10/2/2016 22:45,9589181850,63763092294,Juniper_GBE_ABHA_BSC-1-7-C11_JIZAN-1-7-C11_JIZ1AH1-03 | (SOUTHERN_ABHA_ABH0027-MX480-2 TO SOUTHERN_JIZAN_JIZ0005-MX104-2),1GbE ABHA_BSC,11DPM12-1-7-C11,10/2/2016 23:00,9796008284,60538131757,Juniper_GBE_ABHA_BSC-1-7-C11_JIZAN-1-7-C11_JIZ1AH1-03 | (SOUTHERN_ABHA_ABH0027-MX480-2 TO SOUTHERN_JIZAN_JIZ0005-MX104-2),1GbE ABHA_BSC,11DPM12-1-7-C11,10/2/2016 23:15,8440733035,54114599426,Juniper_GBE_ABHA_BSC-1-7-C11_JIZAN-1-7-C11_JIZ1AH1-03 | (SOUTHERN_ABHA_ABH0027-MX480-2 TO SOUTHERN_JIZAN_JIZ0005-MX104-2),1GbE ABHA_BSC,11DPM12-1-7-C11,10/2/2016 23:30,8051347485,49383381691,Juniper_GBE_ABHA_BSC-1-7-C11_JIZAN-1-7-C11_JIZ1AH1-03 | (SOUTHERN_ABHA_ABH0027-MX480-2 TO SOUTHERN_JIZAN_JIZ0005-MX104-2),1GbE
In awk: $ cat program.awk function mkdt(str) { # functionize dt conversion split(str, a, "[/ ]") # split dt return sprintf( "%s-%02d-%02d %s\n" ,a[3], a[2], a[1], a[4]) # zeropad and reorganize } mkdt($3) > mkdt(start) && mkdt($3) < mkdt(end) # compare and print Run it: $ awk -v start="10/2/2016 23:00" -v end="11/2/2016 20:45" -F, -f program.awk temp.csv ABHA_BSC,11DPM12-1-7-C1,10/2/2016 23:15,6623893225,42756482355,Juniper_GBE_ABHA_BSC-1-7-C1_JIZAN-1-7-C1_JIZ1AH1-01 | (SOUTHERN_ABHA_ABH0027-MX480-1 TO SOUTHERN_JIZAN_JIZ0005-MX104-1),1GbE ABHA_BSC,11DPM12-1-7-C1,10/2/2016 23:30,6781639211,44625787536,Juniper_GBE_ABHA_BSC-1-7-C1_JIZAN-1-7-C1_JIZ1AH1-01 | (SOUTHERN_ABHA_ABH0027-MX480-1 TO SOUTHERN_JIZAN_JIZ0005-MX104-1),1GbE ABHA_BSC,11DPM12-1-7-C1,10/2/2016 23:45,6586403766,41882620412,Juniper_GBE_ABHA_BSC-1-7-C1_JIZAN-1-7-C1_JIZ1AH1-01 | (SOUTHERN_ABHA_ABH0027-MX480-1 TO SOUTHERN_JIZAN_JIZ0005-MX104-1),1GbE ABHA_BSC,11DPM12-1-7-C11,10/2/2016 23:15,8440733035,54114599426,Juniper_GBE_ABHA_BSC-1-7-C11_JIZAN-1-7-C11_JIZ1AH1-03 | (SOUTHERN_ABHA_ABH0027-MX480-2 TO SOUTHERN_JIZAN_JIZ0005-MX104-2),1GbE ABHA_BSC,11DPM12-1-7-C11,10/2/2016 23:30,8051347485,49383381691,Juniper_GBE_ABHA_BSC-1-7-C11_JIZAN-1-7-C11_JIZ1AH1-03 | (SOUTHERN_ABHA_ABH0027-MX480-2 TO SOUTHERN_JIZAN_JIZ0005-MX104-2),1GbE I only zeropad the day and month (1/1/2016 -> 2016-01-01), not the hours or minutes. There is no sanity checking for missing or distorted datetimes. Add = to comparisons if needed (ie. > -> >=).
Using Closure_tree gem instead of Awesome nested set
Hi I followed the link to set up closure_tag gem. When i tried to use closure_tree syntax in the following way (newStructure.find_or_create_by_path(parent) instead of newStructure.move_to_child_of(parent)) ... got the following error : "Can't mass-assign protected attributes: ancestor, descendant, generations" is this the correct way of using newStructure.find_or_create_by_path(parent) ? def self.import(path) newStructure = FileOrFolder.find(:first, :conditions=>["fullpath = ?", path]) if newStructure return newStructure end newStructure = FileOrFolder.new newStructure.fullpath = path pathbits = path.split('/') newStructure.name = pathbits.last newStructure.save parentpath = path.sub(/#{Regexp.escape(pathbits.last)}$/, '') if parentpath.length > 1 parentpath.sub!(/\/$/,'') parent = FileOrFolder.find(:first, :conditions=>["fullpath = ?", parentpath]) unless parent parent = FileOrFolder.import(parentpath) end #newStructure.move_to_child_of(parent); **newStructure.find_or_create_by_path(parent);** end newStructure.save return newStructure end database table looks like : mysql> select * from testdb7.file_or_folders limit 10; +------+-----------+------+------+----------+------------------------+---------------------+---------------------+ | id | parent_id | lft | rgt | fullpath | name | created_at | updated_at | +------+-----------+------+------+----------+------------------------+---------------------+---------------------+ | 6901 | NULL | NULL | NULL | NULL | | 2013-06-25 18:49:04 | 2013-06-25 18:49:04 | | 6902 | 6901 | NULL | NULL | NULL | devel | 2013-06-25 18:49:04 | 2013-06-25 18:49:04 | | 6903 | 6902 | NULL | NULL | NULL | Bcontrol | 2013-06-25 18:49:04 | 2013-06-25 18:49:04 | | 6904 | 6903 | NULL | NULL | NULL | perfect | 2013-06-25 18:49:04 | 2013-06-25 18:49:04 | | 6905 | 6904 | NULL | NULL | NULL | matlab | 2013-06-25 18:49:04 | 2013-06-25 18:49:04 | | 6906 | 6905 | NULL | NULL | NULL | test | 2013-06-25 18:49:04 | 2013-06-25 18:49:04 | | 6907 | 6906 | NULL | NULL | NULL | smoke | 2013-06-25 18:49:04 | 2013-06-25 18:49:04 | | 6908 | 6907 | NULL | NULL | NULL | Control_System_Toolbox | 2013-06-25 18:49:04 | 2013-06-25 18:49:04 | | 6909 | 6908 | NULL | NULL | NULL | tsmoke_are.m | 2013-06-25 18:49:04 | 2013-06-25 18:49:04 | | 6910 | 6908 | NULL | NULL | NULL | tsmoke_bode.m | 2013-06-25 18:49:04 | 2013-06-25 18:49:04 | +------+-----------+------+------+----------+------------------------+---------------------+---------------------+ FileOrFolder Load (14560.8ms) SELECT `file_or_folders`.* FROM `file_or_folders` INNER JOIN `file_or_folder_hierarchies` ON `file_or_folders`.`id` = `file_or_folder_hierarchies`.`descendant_id` INNER JOIN ( SELECT ancestor_id FROM `file_or_folder_hierarchies` GROUP BY 1 HAVING MAX(`file_or_folder_hierarchies`.generations) = 0 ) AS leaves ON (`file_or_folders`.id = leaves.ancestor_id) WHERE `file_or_folder_hierarchies`.`ancestor_id` = 147 ORDER BY `file_or_folder_hierarchies`.generations asc EXPLAIN (13343.7ms) EXPLAIN SELECT `file_or_folders`.* FROM `file_or_folders` INNER JOIN `file_or_folder_hierarchies` ON `file_or_folders`.`id` = `file_or_folder_hierarchies`.`descendant_id` INNER JOIN ( SELECT ancestor_id FROM `file_or_folder_hierarchies` GROUP BY 1 HAVING MAX(`file_or_folder_hierarchies`.generations) = 0 ) AS leaves ON (`file_or_folders`.id = leaves.ancestor_id) WHERE `file_or_folder_hierarchies`.`ancestor_id` = 147 ORDER BY `file_or_folder_hierarchies`.generations asc EXPLAIN for: SELECT `file_or_folders`.* FROM `file_or_folders` INNER JOIN `file_or_folder_hierarchies` ON `file_or_folders`.`id` = `file_or_folder_hierarchies`.`descendant_id` INNER JOIN ( SELECT ancestor_id FROM `file_or_folder_hierarchies` GROUP BY 1 HAVING MAX(`file_or_folder_hierarchies`.generations) = 0 ) AS leaves ON (`file_or_folders`.id = leaves.ancestor_id) WHERE `file_or_folder_hierarchies`.`ancestor_id` = 147 ORDER BY `file_or_folder_hierarchies`.generations asc +----+-------------+----------------------------+--------+------------------------------------------------------------------------------------+----------------------------------+---------+--------------------+---------+---------------------------------+ | id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra | +----+-------------+----------------------------+--------+------------------------------------------------------------------------------------+----------------------------------+---------+--------------------+---------+---------------------------------+ | 1 | PRIMARY | file_or_folder_hierarchies | ref | index_file_or_folders_on_ans_des,index_file_or_folder_hierarchies_on_descendant_id | index_file_or_folders_on_ans_des | 4 | const | 15 | Using temporary; Using filesort | | 1 | PRIMARY | <derived2> | ALL | NULL | NULL | NULL | NULL | 104704 | Using where; Using join buffer | | 1 | PRIMARY | file_or_folders | eq_ref | PRIMARY | PRIMARY | 4 | leaves.ancestor_id | 1 | Using where | | 2 | DERIVED | file_or_folder_hierarchies | index | NULL | index_file_or_folders_on_ans_des | 8 | NULL | 1340096 | | +----+-------------+----------------------------+--------+------------------------------------------------------------------------------------+----------------------------------+---------+--------------------+---------+---------------------------------+
I'm the author of closure_tree. 4.2.3 is on it's way with the fix for attr_accessible. I'm just waiting for Travis to finish testing it. It looks like your whole import method could be replaced with this line: # Assumes that path is a string that looks like this: "/usr/local/bin/ruby" def import(path) FileOrFolder.find_or_create_by_path(path.split("/")) end This assumes you have this FileOrFolder setup: class FileOrFolder < ActiveRecord::Base acts_as_tree before_create :set_fullpath def set_fullpath if root? self.fullpath = "/#{name}" else self.fullpath = "/#{parent.ancestry_path.join("/")}/#{name}" end end end Please take a look at the spec directory. You'll find tons of other examples.
Orbeon session expired handling
In ORBEON 4.1 is very strange session expired error handling ... When using DEV mode, than we get plain text error page +----------------------------------------------------------------------------------------------------------------------+ |An Error has Occurred | |----------------------------------------------------------------------------------------------------------------------| |Session has expired. Unable to process incoming request. | |----------------------------------------------------------------------------------------------------------------------| |Application Call Stack | |----------------------------------------------------------------------------------------------------------------------| |oxf:/ops/xforms/xforms-server-submit.xpl | 72| 51|executing processor | |oxf:/ops/pfc/xforms-xml-submission.xpl | 50| 46|executing processor | |----------------------------------------------------------------------------------------------------------------------| |Exception: org.orbeon.oxf.common.OXFException | |----------------------------------------------------------------------------------------------------------------------| |org.orbeon.oxf.xforms.state.XFormsStateManager |extractParameters |XFormsStateManager.java | 403| |org.orbeon.oxf.xforms.processor.XFormsServer |doIt |XFormsServer.java | 152| |org.orbeon.oxf.xforms.processor.XFormsServer |start |XFormsServer.java | 100| |org.orbeon.oxf.processor.pipeline.PipelineProcessor|run |PipelineProcessor.java | 617| |----------------------------------------------------------------------------------------------------------------------| |Exception: org.orbeon.oxf.common.ValidationException | |----------------------------------------------------------------------------------------------------------------------| |org.orbeon.oxf.common.ValidationException |wrapException |ValidationException.java | 126| |org.orbeon.oxf.processor.pipeline.PipelineProcessor|run |PipelineProcessor.java | 619| |org.orbeon.oxf.processor.pipeline.PipelineProcessor|executeChildren |PipelineProcessor.java | 679| |org.orbeon.oxf.processor.pipeline.PipelineProcessor|start |PipelineProcessor.java | 614| |org.orbeon.oxf.processor.pipeline.choose.ConcreteCh|start |ConcreteChooseProcessor.java | 248| |org.orbeon.oxf.processor.pipeline.PipelineProcessor|run |PipelineProcessor.java | 617| |org.orbeon.oxf.processor.pipeline.PipelineProcessor|executeChildren |PipelineProcessor.java | 679| |org.orbeon.oxf.processor.pipeline.PipelineProcessor|start |PipelineProcessor.java | 614| |org.orbeon.oxf.processor.pipeline.PipelineProcessor|run |PipelineProcessor.java | 617| |org.orbeon.oxf.processor.pipeline.PipelineProcessor|executeChildren |PipelineProcessor.java | 679| |org.orbeon.oxf.processor.pipeline.PipelineProcessor|start |PipelineProcessor.java | 614| |org.orbeon.oxf.processor.pipeline.PipelineProcessor|getInput |PipelineProcessor.java | 140| |org.orbeon.oxf.processor.pipeline.PipelineProcessor|readImpl |PipelineProcessor.java | 83| |org.orbeon.oxf.processor.impl.ProcessorOutputImpl$T|read |ProcessorOutputImpl.java | 258| |org.orbeon.oxf.processor.impl.ProcessorOutputImpl |read |ProcessorOutputImpl.java | 404| |org.orbeon.oxf.processor.pipeline.choose.ConcreteCh|readImpl |ConcreteChooseProcessor.java | 127| |org.orbeon.oxf.processor.impl.ProcessorOutputImpl$T|read |ProcessorOutputImpl.java | 258| |org.orbeon.oxf.processor.impl.ProcessorOutputImpl |read |ProcessorOutputImpl.java | 404| |org.orbeon.oxf.processor.ProcessorImpl |readInputAsSAX |ProcessorImpl.java | 262| |org.orbeon.oxf.processor.pipeline.PipelineProcessor|run |PipelineProcessor.java | 92| |---8<--------8<--------8<--------8<--------8<--------8<--------8<--------8<--------8<--------8<--------8<--------8<---| |org.orbeon.oxf.webapp.ProcessorService |service |ProcessorService.scala | 40| |org.orbeon.oxf.servlet.OrbeonServlet$$anonfun$servi|apply$mcV$sp |OrbeonServlet.scala | 74| |org.orbeon.oxf.servlet.OrbeonServlet$$anonfun$servi|apply |OrbeonServlet.scala | 67| |org.orbeon.oxf.servlet.OrbeonServlet$$anonfun$servi|apply |OrbeonServlet.scala | 67| |org.orbeon.oxf.util.ScalaUtils$ |withRootException |ScalaUtils.scala | 118| |org.orbeon.oxf.servlet.OrbeonServlet |service |OrbeonServlet.scala | 67| |javax.servlet.http.HttpServlet |service |HttpServlet.java | 820| |weblogic.servlet.internal.StubSecurityHelper$Servle|run |StubSecurityHelper.java | 227| |weblogic.servlet.internal.StubSecurityHelper |invokeServlet |StubSecurityHelper.java | 125| |weblogic.servlet.internal.ServletStubImpl |execute |ServletStubImpl.java | 300| |weblogic.servlet.internal.ServletStubImpl |execute |ServletStubImpl.java | 183| |weblogic.servlet.internal.WebAppServletContext$Serv|doIt |WebAppServletContext.java |3683| |weblogic.servlet.internal.WebAppServletContext$Serv|run |WebAppServletContext.java |3650| |weblogic.security.acl.internal.AuthenticatedSubject|doAs |AuthenticatedSubject.java | 321| |weblogic.security.service.SecurityManager |runAs |SecurityManager.java | 121| |weblogic.servlet.internal.WebAppServletContext |securedExecute |WebAppServletContext.java |2268| |weblogic.servlet.internal.WebAppServletContext |execute |WebAppServletContext.java |2174| |weblogic.servlet.internal.ServletRequestImpl |run |ServletRequestImpl.java |1446| |weblogic.work.ExecuteThread |execute |ExecuteThread.java | 201| |weblogic.work.ExecuteThread |run |ExecuteThread.java | 173| +----------------------------------------------------------------------------------------------------------------------+ It should be OK (its in DEV mode by the way ...), but if we switch to PROD mode, than user got plain Error occurred error without error details. Session timeout is very common error and we need show to user user friendly page with instruction what to do. Is there any way how to do it?