1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203 |
- MODULE Repositories; (** AUTHOR "staubesv"; PURPOSE "Component repositories"; *)
- IMPORT
- Streams, Modules, KernelLog, Commands, Strings, Files, Archives, Localization,
- UTF8Strings, XML, XMLObjects, XMLScanner, XMLParser, WMEvents;
- CONST
- Ok* = 0;
- NotFound* = 10;
- RepositoryNotFound* = 11;
- ComponentNotFound* = 12;
- RepositoryNotLoaded* = 13;
- DuplicateName* = 20;
- DuplicateID* = 21;
- DuplicateRepository* = 22;
- IndexError* = 50;
- CannotCreateArchive* = 100;
- ArchivesError* = 101;
- WrongVersion* = 200;
- FormatError* = 201;
- ParseError* = 300;
- DictionaryNotFound* = 400;
- LanguageNotAvailable* = 410;
- LanguageFileNotFound* = 420;
- InternalError* = 999;
- (* Component.flags *)
- Generated = 0; (* this component composite was generated by a generator procedure *)
- Locked = 1; (* this component composite is part of a loaded component *)
- IndexFile = "index.xml";
- DefaultFileExtension* = "rep";
- Delimiter* = ":";
- PrototypeID = 0;
- (* Header information *)
- Version = 1;
- Quote = '"';
- EscapeCharacter = "&";
- EscapeQuote = """;
- (* IndexEntry.type *)
- Type_Component = 1;
- Type_Generator = 2;
- CommandPrefix* = "cmd:";
- (* Strings used in XML index file *)
- XmlRepository = "Repository";
- XmlComponents = "Components";
- XmlComponent = "Component";
- XmlDictionaries = "Dictionaries";
- XmlDictionary = "Dictionary";
- XmlLanguage = "Language";
- XmlApplications = "Applications";
- XmlApplication = "Application";
- XmlAttributeName = "name";
- XmlAttributeDefault = "default";
- XmlAttributeID = "id";
- XmlAttributeSource = "source";
- TraceLoading = 0;
- TraceInstantiate = 1;
- TraceCreation = 2;
- Trace = {};
- TYPE
- Context* = OBJECT(Commands.Context)
- VAR
- object* : ANY;
- PROCEDURE &Init*(in, arg : Streams.Reader; out, error : Streams.Writer; caller: OBJECT);
- BEGIN
- Init^(in, arg, out, error, caller);
- object := NIL;
- END Init;
- END Context;
- StoreContext*= OBJECT
- VAR repository-: Repository;
- PROCEDURE &InitStoreContext(r: Repository);
- BEGIN
- repository := r;
- END InitStoreContext;
- END StoreContext;
- Command* = PROCEDURE {DELEGATE} (context : Context);
- TYPE
- (** Base class of all components *)
- Component* = OBJECT(XML.Element)
- VAR
- repository : Repository; name : Strings.String; refNum : LONGINT;
- flags : SET;
- timestamp- : LONGINT;
- onChanged* : WMEvents.EventSource; (* for update mechanisms, basically every component needs a feature to inform about updates *)
- PROCEDURE &Init*;
- BEGIN
- Init^;
- repository := NIL; name := NIL; refNum := 0;
- flags := {};
- timestamp := 0;
- NEW(onChanged, NIL, NIL, NIL, NIL);
- END Init;
- PROCEDURE SetGenerator*(CONST gen: ARRAY OF CHAR);
- BEGIN SetAttributeValue("generator", gen);
- END SetGenerator;
- PROCEDURE SetRepository*(repository : Repository; CONST name : Name; refNum : LONGINT);
- BEGIN {EXCLUSIVE}
- SELF.repository := repository; SELF.refNum := refNum;
- IF (repository # NIL) THEN
- SELF.name := Strings.NewString(name);
- SetNameAsString(SELF.name);
- (*
- SetNameAsString(NewJoinName(repository.name, name, refNum));
- *)
- ELSE
- IF (SELF.name # NIL) THEN
- SetNameAsString(SELF.name);
- SELF.name := NIL;
- ELSE
- SetName("Unbound");
- END;
- END;
- INC(timestamp);
- END SetRepository;
- PROCEDURE GetRepository*(VAR repository : Repository; VAR name : Name; VAR refNum : LONGINT);
- BEGIN {EXCLUSIVE}
- repository := SELF.repository; refNum := SELF.refNum;
- IF (SELF.name # NIL) THEN COPY(SELF.name^, name); ELSE name := ""; END;
- END GetRepository;
- PROCEDURE IsLocked*() : BOOLEAN;
- BEGIN
- RETURN Locked IN flags;
- END IsLocked;
- PROCEDURE FromXML*(xml: XML.Element);
- VAR component: Component; enum: XMLObjects.Enumerator; c: ANY;
- BEGIN
- enum := xml.GetContents();
- WHILE enum.HasMoreElements() DO
- c := enum.GetNext();
- IF c IS XML.Element THEN
- component := ComponentFromXML(c(XML.Element));
- IF component # NIL THEN
- AddContent(component)
- END;
- END;
- END;
- END FromXML;
- END Component;
- TYPE
- Name* = ARRAY 32 OF CHAR;
- ApplicationInfo = OBJECT(XML.Element)
- END ApplicationInfo;
- ComponentInfo = OBJECT(XML.Element)
- VAR
- name, source : Strings.String; (* { (name # NIL) & (source # NIL) } *)
- type, id : LONGINT;
- instance : ANY;
- next : ComponentInfo;
- PROCEDURE &Init*;
- BEGIN
- Init^;
- SetNameAsString(StrComponent);
- name := StrNoName;
- source := StrNoName;
- type := Type_Generator; id := 0;
- instance := NIL;
- next := NIL;
- END Init;
- PROCEDURE AddAttribute*(attribute : XML.Attribute);
- VAR name, temp : Strings.String;
- BEGIN
- name := attribute.GetName();
- IF (name # NIL) THEN
- IF (name^ = XmlAttributeName) THEN
- SELF.name := attribute.GetValue();
- IF (SELF.name = NIL) THEN SELF.name := StrNoName; END;
- ELSIF (name^ = XmlAttributeID) THEN
- temp := attribute.GetValue();
- IF (temp # NIL) THEN
- Strings.StrToInt(temp^, SELF.id);
- END;
- ELSIF (name^ = XmlAttributeSource) THEN
- temp := attribute.GetValue();
- IF (temp # NIL) THEN
- source := temp;
- IF IsXmlFilename(source^) THEN
- type := Type_Component;
- ELSE
- type := Type_Generator;
- END;
- ELSE
- source := StrNoName;
- END;
- END;
- END;
- AddAttribute^(attribute);
- END AddAttribute;
- END ComponentInfo;
- TYPE
- IndexRegistry* = OBJECT(XML.ElementRegistry)
- PROCEDURE InstantiateElement*(CONST name: ARRAY OF CHAR): XML.Element;
- VAR element : XML.Element; appInfo : ApplicationInfo; comInfo : ComponentInfo; repository : Repository; dictionary : Dictionary;
- BEGIN
- element := NIL;
- IF (name = XmlApplication) THEN
- NEW(appInfo); element := appInfo;
- ELSIF (name = XmlComponent) THEN
- NEW(comInfo); element := comInfo;
- ELSIF (name = XmlRepository) THEN
- NEW(repository); element := repository;
- ELSIF (name = XmlDictionary) THEN
- NEW(dictionary); element := dictionary;
- END;
- RETURN element;
- END InstantiateElement;
- END IndexRegistry;
- TYPE
- Entry = OBJECT
- VAR
- word, translation : Strings.String;
- next : Entry;
- PROCEDURE &Init(word, translation : Strings.String);
- BEGIN
- ASSERT((word # NIL) & (translation # NIL));
- SELF.word := word;
- SELF.translation := translation;
- next := NIL;
- END Init;
- END Entry;
- TYPE
- Translator = OBJECT
- VAR
- entries : Entry;
- PROCEDURE &Init;
- BEGIN
- entries := NIL;
- END Init;
- PROCEDURE Add(word, translation : Strings.String);
- VAR e, newEntry : Entry;
- BEGIN
- ASSERT((word # NIL) & (translation # NIL));
- e := Find(word^);
- IF (e = NIL) THEN
- NEW(newEntry, word, translation);
- IF (entries = NIL) THEN
- entries := newEntry;
- ELSIF (UTF8Strings.Compare(word^, entries.word^) # UTF8Strings.CmpLess) THEN
- newEntry.next := entries;
- entries := newEntry;
- ELSE
- e := entries;
- WHILE (e.next # NIL) & (UTF8Strings.Compare(word^, e.next.word^) = UTF8Strings.CmpLess) DO e := e.next; END;
- newEntry.next := e.next;
- e.next := newEntry;
- END;
- ELSE
- KernelLog.String("Repositories.Translator: Warning: Ignoring duplicate dictionary entry (");
- KernelLog.String(word^); KernelLog.String(", "); KernelLog.String(translation^); KernelLog.String(")");
- KernelLog.Ln;
- END;
- END Add;
- PROCEDURE Parse(reader : Streams.Reader; VAR res : WORD);
- VAR buffer : Strings.Buffer; entry : Entry; ch : CHAR;
- PROCEDURE ReportError(CONST msg : ARRAY OF CHAR; position : LONGINT);
- BEGIN
- KernelLog.String("Repositories.Dictionary.Parse: Error: "); KernelLog.String(msg);
- KernelLog.String(" at position "); KernelLog.Int(position, 0); KernelLog.Ln;
- END ReportError;
- (* Read all characters until '"' OR 0X (excl) *)
- PROCEDURE GetString(reader : Streams.Reader) : Strings.String;
- VAR temp : Strings.String; writer : Streams.Writer; escaping : BOOLEAN; escape : ARRAY 8 OF CHAR; i : LONGINT;
- BEGIN
- ASSERT(reader # NIL);
- buffer.Clear;
- writer := buffer.GetWriter();
- escaping := FALSE;
- ch := reader.Peek();
- WHILE (ch # Quote) & (ch # 0X) DO
- ch := reader.Get();
- IF (ch = EscapeCharacter) THEN
- IF (escaping) THEN writer.String(escape); ELSE escaping := TRUE; END;
- escape[0] := EscapeCharacter;
- escape[1] := 0X;
- i := 1;
- ELSIF escaping THEN
- escape[i] := ch;
- escape[i + 1] := 0X;
- INC(i);
- IF Strings.Length(escape) = Strings.Length(EscapeQuote) THEN
- escaping := FALSE;
- IF (escape = EscapeQuote) THEN
- writer.Char(Quote);
- ELSE
- writer.String(escape);
- END;
- END;
- ELSE
- writer.Char(ch);
- END;
- ch := reader.Peek();
- END;
- IF escaping THEN writer.String(escape); END;
- temp := buffer.GetString();
- RETURN Strings.NewString(temp^);
- END GetString;
- (** Parse and generate one entry of the form "word"="translation" *)
- PROCEDURE ParseEntry(reader : Streams.Reader) : BOOLEAN;
- VAR ch : CHAR; word, translation : Strings.String;
- BEGIN
- ASSERT(reader # NIL);
- entry := NIL;
- reader.SkipWhitespace;
- ch := reader.Get();
- IF (ch = Quote) THEN
- word := GetString(reader);
- ch := reader.Get();
- IF (ch = Quote) THEN
- reader.SkipWhitespace;
- ch := reader.Get();
- IF (ch = "=") THEN
- reader.SkipWhitespace;
- ch := reader.Get();
- IF (ch = Quote) THEN
- translation := GetString(reader);
- ch := reader.Get();
- IF (ch = Quote) THEN
- Add(word, translation);
- RETURN TRUE;
- ELSE
- ReportError("Expected closing quote", reader.Pos() - 1);
- END;
- ELSE
- ReportError("Expected opening quote", reader.Pos() - 1);
- END;
- ELSE
- ReportError("Expected equal sign", reader.Pos() - 1);
- END;
- ELSE
- ReportError("Expected closing quote", reader.Pos() - 1);
- END;
- ELSE
- ReportError("Expected opening quote", reader.Pos() - 1);
- END;
- RETURN FALSE;
- END ParseEntry;
- BEGIN
- ASSERT(reader # NIL);
- NEW(buffer, 512);
- reader.SkipWhitespace;
- ch := reader.Peek();
- WHILE (ch # 0X) & ParseEntry(reader) DO
- reader.SkipWhitespace;
- ch := reader.Peek();
- END;
- IF (ch = 0X) THEN
- res := Ok;
- ELSE
- res := ParseError;
- END;
- END Parse;
- PROCEDURE Find(CONST word : ARRAY OF CHAR) : Entry;
- VAR e : Entry; result : LONGINT;
- BEGIN
- result := UTF8Strings.CmpLess;
- e := entries;
- LOOP
- IF (e = NIL) THEN EXIT; END;
- result := UTF8Strings.Compare(word, e.word^);
- IF (result # UTF8Strings.CmpLess) THEN
- EXIT;
- ELSE
- e := e.next;
- END;
- END;
- IF (result = UTF8Strings.CmpEqual) THEN
- ASSERT(e # NIL);
- RETURN e;
- ELSE
- RETURN NIL;
- END;
- END Find;
- PROCEDURE ComplexTranslation(CONST word : ARRAY OF CHAR) : Strings.String;
- VAR buf : ARRAY 1024 OF CHAR; i, j : LONGINT; translation : Strings.String; w : Name;
- PROCEDURE BoundsCheck() : BOOLEAN;
- BEGIN
- RETURN (i < LEN(word)) & (j < LEN(buf) - 1);
- END BoundsCheck;
- PROCEDURE Append;
- BEGIN
- WHILE BoundsCheck() & (word[i] # 0X) & (word[i] # ":") DO
- buf[j] := word[i];
- INC(j); INC(i);
- END;
- END Append;
- PROCEDURE AppendTranslation(CONST translation : ARRAY OF CHAR);
- VAR idx : LONGINT;
- BEGIN
- idx := 0;
- WHILE (j < LEN(buf) - 1) & (idx < LEN(translation)) & (translation[idx] # 0X) DO
- buf[j] := translation[idx];
- INC(j); INC(idx);
- END;
- buf[j] := 0X;
- END AppendTranslation;
- PROCEDURE GetName(VAR w : ARRAY OF CHAR) : BOOLEAN;
- VAR getName : BOOLEAN; idx : LONGINT;
- BEGIN
- getName := TRUE;
- w := "";
- WHILE BoundsCheck() & (word[i] = ":") DO (** unescape :: to : *)
- IF getName THEN buf[j] := ":"; getName := FALSE; ELSE getName := TRUE; END;
- INC(i);
- END;
- IF getName THEN
- idx := 0;
- WHILE (i < LEN(word)) & (word[i] # 0X) & (word[i] # ":") DO
- IF (idx < LEN(w) - 1) THEN
- w[idx] := word[i];
- INC(idx);
- END;
- INC(i);
- END;
- w[idx] := 0X;
- IF (i < LEN(word)) & (word[i] = ":") THEN INC(i); END;
- END;
- RETURN getName & (w # "");
- END GetName;
- BEGIN
- i := 0; j := 0;
- WHILE BoundsCheck() & (word[i] # 0X) DO
- Append;
- IF BoundsCheck() & (word[i] = ":") THEN
- INC(i); (* skip ":" *)
- IF GetName(w) THEN
- ASSERT(Strings.Count(w, ":") = 0);
- translation := TranslateAOC(w);
- ASSERT(translation # NIL);
- AppendTranslation(translation^);
- END;
- END;
- END;
- buf[j] := 0X;
- RETURN Strings.NewString(buf);
- END ComplexTranslation;
- PROCEDURE TranslateAOC(CONST word : ARRAY OF CHAR) : Strings.String;
- VAR result : Strings.String; entry : Entry;
- BEGIN
- IF Strings.Count(word, ":") = 0 THEN
- entry := Find(word);
- IF (entry # NIL) THEN
- result := entry.translation;
- ELSE
- result := Strings.NewString(word);
- END;
- ELSE
- result := ComplexTranslation(word);
- END;
- ASSERT(result # NIL);
- RETURN result;
- END TranslateAOC;
- PROCEDURE Translate(word : Strings.String) : Strings.String;
- VAR result : Strings.String; entry : Entry;
- BEGIN
- ASSERT(word # NIL);
- IF Strings.Count(word^, ":") = 0 THEN (* simple translation *)
- entry := Find(word^);
- IF (entry # NIL) THEN
- result := entry.translation;
- ELSE
- result := word;
- END;
- ELSE
- result := ComplexTranslation(word^);
- END;
- ASSERT(result # NIL);
- RETURN result;
- END Translate;
- END Translator;
- TYPE
- Language = RECORD
- code : ARRAY 3 OF CHAR;
- source : Files.FileName;
- translator : Translator;
- error, default : BOOLEAN;
- END;
- TYPE
- Dictionary* = OBJECT(XML.Element)
- VAR
- fullname- : Strings.String; (* {fullname # NIL} *)
- name : Strings.String;
- languages : POINTER TO ARRAY OF Language;
- repository : Repository;
- next : Dictionary;
- PROCEDURE &Init*;
- BEGIN
- Init^;
- fullname := StrNoName;
- name := StrNoName;
- languages := NIL;
- repository := NIL;
- next := NIL;
- END Init;
- PROCEDURE Initialize;
- VAR temp : ARRAY 256 OF CHAR;
- BEGIN
- ASSERT(repository # NIL);
- COPY(repository.name, temp); Strings.Append(temp, ":"); Strings.Append(temp, name^);
- fullname := Strings.NewString(temp);
- InitializeLanguages;
- END Initialize;
- PROCEDURE InitializeLanguages;
- VAR
- enum : XMLObjects.Enumerator; string : Strings.String; ptr : ANY;
- nofLanguages, i : LONGINT;
- BEGIN
- nofLanguages := 0;
- enum := GetContents();
- WHILE enum.HasMoreElements() DO
- ptr := enum.GetNext();
- IF (ptr IS XML.Element) THEN
- string := ptr(XML.Element).GetName();
- IF (string # NIL) & (string^ = XmlLanguage) & (ptr(XML.Element).GetAttributeValue(XmlAttributeName) # NIL) THEN
- INC(nofLanguages);
- END;
- END;
- END;
- IF (nofLanguages > 0) THEN
- NEW(languages, nofLanguages);
- i := 0;
- enum.Reset;
- WHILE enum.HasMoreElements() DO
- ptr := enum.GetNext();
- IF (ptr IS XML.Element) THEN
- string := ptr(XML.Element).GetName();
- IF (string # NIL) & (string^ = XmlLanguage) THEN
- string := ptr(XML.Element).GetAttributeValue(XmlAttributeName);
- IF (string # NIL) THEN
- COPY(string^, languages[i].code);
- string := ptr(XML.Element).GetAttributeValue(XmlAttributeSource);
- IF (string # NIL) THEN
- COPY(string^, languages[i].source);
- END;
- string := ptr(XML.Element).GetAttributeValue(XmlAttributeDefault);
- languages[i].default := (string # NIL) & (string^ = "true");
- languages[i].translator := NIL;
- languages[i].error := FALSE;
- INC(i);
- END;
- END;
- END;
- END;
- END;
- END InitializeLanguages;
- PROCEDURE Find(CONST language : Localization.Language) : Translator;
- VAR t : Translator; res: WORD; i : LONGINT;
- BEGIN
- t := NIL;
- IF (languages # NIL) THEN
- i := 0;
- WHILE (i < LEN(languages)) & (languages[i].code # language.code) DO INC(i); END;
- IF (i < LEN(languages)) THEN
- t := languages[i].translator;
- IF (t = NIL) & ~languages[i].error THEN
- LoadLanguage(languages[i], res);
- IF (res = Ok) THEN
- t := languages[i].translator;
- ELSE
- KernelLog.String("Repositories.Dictionary ");
- IF (name # NIL) THEN KernelLog.String(name^); ELSE KernelLog.String("UNKNOWN"); END;
- KernelLog.String(": ERROR: Could not load language file "); KernelLog.String(languages[i].source);
- KernelLog.String(", res = "); KernelLog.Int(res, 0); KernelLog.Ln;
- END;
- END;
- END;
- END;
- RETURN t;
- END Find;
- PROCEDURE GetDefaultTranslator() : Translator;
- VAR t : Translator; i: LONGINT; res : WORD;
- BEGIN
- t := NIL;
- IF (languages # NIL) THEN
- i := 0;
- WHILE (i < LEN(languages)) & ~languages[i].default DO INC(i); END;
- IF (i < LEN(languages)) THEN
- t := languages[i].translator;
- IF (t = NIL) & ~languages[i].error THEN
- LoadLanguage(languages[i], res);
- IF (res = Ok) THEN
- t := languages[i].translator;
- END;
- END;
- END;
- END;
- RETURN t;
- END GetDefaultTranslator;
- PROCEDURE FindBestMatch(languages : Localization.Languages) : Translator;
- VAR translator : Translator; i : LONGINT;
- BEGIN
- ASSERT(languages # NIL);
- translator := NIL;
- i := 0;
- WHILE (translator = NIL) & (i < LEN(languages)) DO
- translator := Find(languages[i]);
- INC(i);
- END;
- IF (translator = NIL) THEN
- translator := GetDefaultTranslator();
- END;
- RETURN translator;
- END FindBestMatch;
- PROCEDURE AddAttribute*(attribute : XML.Attribute);
- VAR name : Strings.String;
- BEGIN
- name := attribute.GetName();
- IF (name # NIL) THEN
- IF (name^ = XmlAttributeName) THEN
- SELF.name := attribute.GetValue();
- IF (SELF.name = NIL) THEN SELF.name := StrNoName; END;
- END;
- END;
- AddAttribute^(attribute);
- END AddAttribute;
- PROCEDURE LoadLanguage(VAR language :Language; VAR res : WORD);
- VAR translator : Translator; reader : Streams.Reader;
- BEGIN {EXCLUSIVE}
- ASSERT(repository # NIL);
- reader := repository.GetFile(language.source);
- IF (reader # NIL) THEN
- NEW(translator);
- translator.Parse(reader, res);
- IF (res = Ok) THEN
- language.translator := translator;
- ELSE
- language.error := TRUE;
- res := ParseError;
- END;
- ELSE
- language.error := TRUE;
- res := LanguageFileNotFound;
- END;
- END LoadLanguage;
- (** Translate UTF8 string 'word' to UTF8 string translation. The resulting string has to be considered immutable! *)
- PROCEDURE TranslateAOC*(CONST word : ARRAY OF CHAR; languages : Localization.Languages) : Strings.String;
- VAR translator : Translator; translation : Strings.String;
- BEGIN
- ASSERT(languages # NIL);
- translator := FindBestMatch(languages);
- IF (translator # NIL) THEN
- translation := translator.TranslateAOC(word);
- ELSE
- translation := Strings.NewString(word);
- END;
- RETURN translation;
- END TranslateAOC;
- (** Translate UTF8 string 'word' to UTF8 string translation. The resulting string has to be considered immutable! *)
- PROCEDURE Translate*(word : Strings.String; languages : Localization.Languages) : Strings.String;
- VAR translator : Translator; translation : Strings.String;
- BEGIN
- ASSERT(languages # NIL);
- IF (word # NIL) THEN
- translator := FindBestMatch(languages);
- IF (translator # NIL) THEN
- translation := translator.Translate(word);
- ELSE
- translation := word;
- END;
- ELSE
- translation := NIL;
- END;
- ASSERT(((word = NIL) & (translation = NIL)) OR ((word # NIL) & (translation # NIL)));
- RETURN translation;
- END Translate;
- PROCEDURE GetLanguages*() : Localization.Languages;
- VAR languages : Localization.Languages; i : LONGINT;
- BEGIN
- IF (SELF.languages # NIL) THEN
- NEW(languages, LEN(SELF.languages));
- FOR i := 0 TO LEN(languages)-1 DO
- COPY(SELF.languages[i].code, languages[i].code);
- END;
- ELSE
- languages := NIL;
- END;
- RETURN languages;
- END GetLanguages;
- END Dictionary;
- TYPE
- Repository* = OBJECT(XML.Element)
- VAR
- name- : Name;
- filename- : Files.FileName;
- archive : Archives.Archive;
- timestamp- : LONGINT;
- modified : BOOLEAN;
- nextID : LONGINT;
- components : ComponentInfo;
- dictionaries : Dictionary;
- errors : ErrorReporter;
- registry-: Registry;
- next : Repository;
- PROCEDURE &Init*;
- BEGIN
- Init^;
- SetNameAsString(StrRepository);
- name := "";
- archive := NIL;
- timestamp := 0;
- modified := FALSE;
- nextID := 0;
- components := NIL;
- dictionaries := NIL;
- NEW(errors);
- NEW(registry, SELF);
- next := NIL;
- END Init;
- (* Post-instantiation initialization *)
- PROCEDURE Initialize() : WORD;
- VAR enum : XMLObjects.Enumerator; ptr : ANY; element : XML.Element; res : WORD;
- BEGIN
- nextID := 0;
- element := FindChild(SELF, "Components");
- IF (element # NIL) THEN
- enum := element.GetContents();
- WHILE enum.HasMoreElements() DO
- ptr := enum.GetNext();
- IF (ptr # NIL) & (ptr IS ComponentInfo) THEN
- ptr(ComponentInfo).next := components;
- components := ptr(ComponentInfo);
- nextID := Strings.Max(nextID, components(ComponentInfo).id);
- END;
- END;
- ELSE
- res := 9934;
- END;
- element := FindChild(SELF, XmlDictionaries);
- IF (element # NIL) THEN
- enum := element.GetContents();
- WHILE enum.HasMoreElements() DO
- ptr := enum.GetNext();
- IF (ptr # NIL) & (ptr IS Dictionary) THEN
- ptr(Dictionary).next := dictionaries;
- dictionaries := ptr(Dictionary);
- dictionaries.repository := SELF;
- dictionaries.Initialize;
- END;
- END;
- END;
- RETURN res;
- END Initialize;
- PROCEDURE FindComponentInfo(CONST name : ARRAY OF CHAR; id : LONGINT) : ComponentInfo;
- VAR ci : ComponentInfo;
- BEGIN
- ci := components;
- WHILE (ci # NIL) & ((ci.name^ # name) OR (ci.id # id)) DO ci := ci.next; END;
- RETURN ci;
- END FindComponentInfo;
- PROCEDURE GetDictionary*(CONST name : ARRAY OF CHAR) : Dictionary;
- VAR d : Dictionary;
- BEGIN
- d := dictionaries;
- WHILE (d # NIL) & (d.name^ # name) DO d := d.next; END;
- RETURN d;
- END GetDictionary;
- PROCEDURE AddComponentInfo(ci : ComponentInfo);
- VAR element : XML.Element;
- BEGIN
- ASSERT(ci # NIL);
- element := FindChild(SELF, XmlComponents);
- ASSERT(element # NIL);
- element.AddContent(ci);
- ci.next := components;
- components := ci;
- END AddComponentInfo;
- PROCEDURE RemoveComponentInfo(ci : ComponentInfo);
- VAR c : ComponentInfo; element : XML.Element;
- BEGIN
- ASSERT(ci # NIL);
- element := FindChild(SELF, XmlComponents);
- ASSERT(element # NIL);
- element.RemoveContent(ci);
- IF (components # NIL) THEN
- IF (components = ci) THEN
- components := components.next;
- ELSE
- c := components;
- WHILE (c.next # NIL) & (c.next # ci) DO c := c.next; END;
- IF (c.next # NIL) THEN c.next := c.next.next; END;
- END;
- END;
- END RemoveComponentInfo;
- PROCEDURE GetComponentEnumerator*() : XMLObjects.Enumerator;
- VAR element : XML.Element;
- BEGIN
- element := FindChild(SELF, XmlComponents);
- ASSERT(element # NIL);
- RETURN element.GetContents();
- END GetComponentEnumerator;
- PROCEDURE GetApplicationEnumerator*() : XMLObjects.Enumerator;
- VAR element : XML.Element;
- BEGIN
- element := FindChild(SELF, XmlApplications);
- ASSERT(element # NIL);
- RETURN element.GetContents();
- END GetApplicationEnumerator;
- PROCEDURE GetFile(CONST name : ARRAY OF CHAR) : Streams.Reader;
- VAR receiver : Streams.Receiver; reader : Streams.Reader;
- BEGIN {EXCLUSIVE}
- reader := NIL;
- archive.Acquire;
- receiver := archive.OpenReceiver(name);
- archive.Release;
- IF (receiver # NIL) THEN
- NEW(reader, receiver, 1024);
- END;
- RETURN reader;
- END GetFile;
- PROCEDURE Check() : BOOLEAN;
- VAR archiveIndex : Archives.Index; error : BOOLEAN; i : LONGINT;
- BEGIN {EXCLUSIVE}
- error := TRUE;
- archive.Acquire;
- archiveIndex := archive.GetIndex();
- IF (archiveIndex # NIL) THEN
- FOR i := 0 TO LEN(archiveIndex)-1 DO
- END;
- END;
- archive.Release;
- RETURN error;
- END Check;
- PROCEDURE GetComponent*(CONST name : ARRAY OF CHAR; id : LONGINT) : Component;
- VAR ci : ComponentInfo; component : Component; cname : Name;
- BEGIN
- IF TraceInstantiate IN Trace THEN
- KernelLog.String("GetComponent: ");
- KernelLog.String(SELF.name); KernelLog.String(":"); KernelLog.String(name); KernelLog.String(":"); KernelLog.Int(id, 0);
- KernelLog.Ln;
- END;
- ci := FindComponentInfo(name, id);
- IF (ci # NIL) & (ci.source # StrNoName) THEN
- IF TraceInstantiate IN Trace THEN
- KernelLog.String("Entry found for "); KernelLog.String(ci.name^);
- KernelLog.String(" (ID="); KernelLog.Int(ci.id, 0); KernelLog.String(", instance: ");
- KernelLog.Boolean(ci.instance # NIL); KernelLog.String(")");
- KernelLog.Ln;
- END;
- IF (ci.instance # NIL) THEN
- ASSERT(ci.id # PrototypeID);
- component := ci.instance(Component);
- IF TraceInstantiate IN Trace THEN KernelLog.String("GetComponent: Reuse!!!"); KernelLog.Ln; END;
- ELSE
- IF (ci.type = Type_Generator) THEN
- component := GenerateComponent(ci.source^);
- ELSIF (ci.type = Type_Component) THEN
- component := LoadComponent(ci.source^);
- END;
- IF (component # NIL) THEN
- IF (ci.type = Type_Generator) THEN
- INCL(component.flags, Generated);
- ELSIF (ci.type = Type_Component) THEN
- (*! what is this for? temporary commented to check persistency implementation.. *)
- (*
- LockChildren(component);
- *)
- END;
- COPY(ci.name^, cname);
- component(Component).SetRepository(SELF, cname, ci.id);
- IF (ci.id # PrototypeID) THEN
- ci.instance := component; (*TBD: Replaced by weak reference *)
- IncrementTimestamp(timestamp);
- END;
- END;
- END;
- ELSIF TraceInstantiate IN Trace THEN
- KernelLog.String("Repositories.GetComponent: Component '"); KernelLog.String(SELF.name); KernelLog.String(":");
- KernelLog.String(name); KernelLog.String(":"); KernelLog.Int(id, 0); KernelLog.String("' not found"); KernelLog.Ln;
- END;
- RETURN component;
- END GetComponent;
- PROCEDURE PutComponent*(component : Component; CONST name : ARRAY OF CHAR; VAR id : LONGINT; VAR res : WORD);
- VAR ci : ComponentInfo; filename : Files.FileName; nbrStr : ARRAY 16 OF CHAR; cname : Name;
- BEGIN
- ASSERT(component # NIL); (* TBD: Locking *)
- ci := components;
- WHILE (ci # NIL) & (ci.instance # component) DO ci := ci.next; END;
- IF (ci # NIL) THEN
- id := ci.id;
- res := Ok;
- RETURN
- END;
- NEW(ci);
- IF (id # 0) THEN id := GetID(); END;
- Strings.IntToStr(id, nbrStr);
- COPY(name, filename); Strings.Append(filename, nbrStr); Strings.Append(filename, ".xml");
- ci.SetAttributeValue(XmlAttributeName, name);
- ci.SetAttributeValue(XmlAttributeID, nbrStr);
- ci.SetAttributeValue(XmlAttributeSource, filename);
- ASSERT(ci.type = Type_Component);
- ci.instance := component;
- StoreComponent(filename, component, res);
- IF (res = Ok) THEN
- AddComponentInfo(ci);
- IF (res = Ok) THEN
- COPY(ci.name^, cname);
- component.SetRepository(SELF, cname, ci.id);
- END;
- ELSE HALT(100);
- END;
- Store(res);
- IncrementTimestamp(timestamp);
- END PutComponent;
- PROCEDURE UnbindComponent*(CONST name : ARRAY OF CHAR; id : LONGINT; VAR res : WORD);
- VAR ci : ComponentInfo;
- BEGIN
- ci := FindComponentInfo(name, id);
- IF (ci # NIL) THEN
- ci.instance := NIL;
- res := Ok;
- ELSE
- res := NotFound;
- END;
- IncrementTimestamp(timestamp);
- END UnbindComponent;
- PROCEDURE Unbind*(component : Component);
- VAR c : ComponentInfo;
- BEGIN
- ASSERT(component # NIL);
- c := components;
- WHILE (c # NIL) & (c.instance # component) DO c := c.next; END;
- IF (c # NIL) THEN
- c.instance := NIL;
- END;
- IncrementTimestamp(timestamp);
- END Unbind;
- PROCEDURE RemoveComponent*(CONST name : ARRAY OF CHAR; refNum : LONGINT; VAR res : WORD);
- VAR ci : ComponentInfo;
- BEGIN
- archive.Acquire;
- ci := FindComponentInfo(name, refNum);
- IF (ci # NIL) THEN
- RemoveComponentInfo(ci);
- IF (ci.type = Type_Component) THEN
- archive.RemoveEntry(ci.source^);
- END;
- res := Ok;
- ELSE
- res := NotFound;
- END;
- archive.Release;
- IncrementTimestamp(timestamp);
- END RemoveComponent;
- PROCEDURE Remove*(component : Component; VAR res : WORD);
- VAR ci : ComponentInfo;
- BEGIN
- ci := components;
- WHILE (ci # NIL) & (ci.instance # component) DO ci := ci.next; END;
- IF (ci # NIL) THEN
- archive.Acquire;
- RemoveComponentInfo(ci);
- IF (ci.type = Type_Component) THEN
- archive.RemoveEntry(ci.source^);
- END;
- archive.Release;
- END;
- IncrementTimestamp(timestamp);
- END Remove;
- PROCEDURE LoadComponent(CONST filename : ARRAY OF CHAR) : Component;
- VAR element : XML.Element; reader : Streams.Reader;
- BEGIN
- IF TraceInstantiate IN Trace THEN
- KernelLog.String("Repositories.Registry.Create: "); KernelLog.String(filename); KernelLog.Ln;
- END;
- element := NIL;
- reader := GetFile(filename);
- IF (reader # NIL) THEN
- IF TraceInstantiate IN Trace THEN KernelLog.String("Repositories.Registry.Create: File found"); KernelLog.Ln; END;
- element := Parse(reader, registry, errors);
- END;
- IF (element # NIL) & (element IS Component) THEN
- RETURN element (Component);
- ELSE
- RETURN NIL;
- END;
- END LoadComponent;
- (* Return an ID that is unique withhin this repository *)
- PROCEDURE GetID*() : LONGINT;
- BEGIN {EXCLUSIVE}
- INC(nextID);
- RETURN nextID;
- END GetID;
- PROCEDURE Store*(VAR res : WORD);
- VAR writer : Streams.Writer;context: StoreContext;
- BEGIN
- archive.Acquire;
- writer := GetWriter(archive, IndexFile);
- IF (writer # NIL) THEN
- NEW(context, SELF);
- Write(writer, context, 0);
- writer.Update;
- ELSE
- res := 99;
- END;
- archive.Release;
- END Store;
- PROCEDURE StoreComponent(CONST filename : ARRAY OF CHAR; component : Component; VAR res : WORD);
- VAR writer : Streams.Writer; context: StoreContext;
- BEGIN
- ASSERT(component # NIL);
- archive.Acquire;
- writer := GetWriter(archive, filename);
- IF (writer # NIL) THEN
- NEW(context, SELF);
- component.Write(writer, context, 0);
- writer.Update;
- res := Ok;
- ELSE
- res := 9912;
- END;
- archive.Release;
- END StoreComponent;
- PROCEDURE Dump*(writer : Streams.Writer);
- BEGIN
- IF (writer = NIL) THEN NEW(writer, KernelLog.Send, 1024); END;
- writer.String("Dump repository "); writer.String(name); writer.String(": "); writer.Ln; writer.Update;
- SELF.Write(writer, NIL, 0); writer.Ln;
- writer.Update;
- END Dump;
- END Repository;
- Repositories* = POINTER TO ARRAY OF Repository;
- Properties* = OBJECT(XML.Element)
- VAR repository-: Repository; (* to pass repository during creation *)
- PROCEDURE &New(r: Repository);
- BEGIN repository := r
- END New;
- END Properties;
- TYPE
- Registry* = OBJECT(XML.ElementRegistry)
- VAR repository: Repository;
- PROCEDURE & InitRegistry(r: Repository);
- BEGIN
- repository := r
- END InitRegistry;
- PROCEDURE InstantiateElement*(CONST name: ARRAY OF CHAR): XML.Element;
- VAR
- repositoryName, componentName : ARRAY 128 OF CHAR; id : LONGINT;
- repository : Repository;
- element : XML.Element;
- properties : Properties;
- BEGIN
- IF TraceInstantiate IN Trace THEN KernelLog.String("Repositories.Registry.InstantiateElement: "); KernelLog.String(name); KernelLog.Ln; END;
- element := NIL;
- IF SplitName(name, repositoryName, componentName, id) THEN
- IF (repositoryName # "") THEN
- repository := ThisRepository(repositoryName);
- IF (repository # NIL) THEN
- element := repository.GetComponent(componentName, id);
- IF TraceInstantiate IN Trace THEN
- KernelLog.String("Repositories.Registry.InstantiateElement: Instantiate component: "); KernelLog.String(componentName); KernelLog.Ln;
- KernelLog.Boolean(element # NIL); KernelLog.Ln;
- END;
- ELSE
- KernelLog.String("Repository not found:"); KernelLog.String(repositoryName); KernelLog.Ln;
- END;
- ELSIF (componentName = "Properties") THEN
- NEW(properties,SELF.repository);
- RETURN properties;
- ELSIF SELF.repository # NIL THEN
- repository := SELF.repository;
- element := repository.GetComponent(componentName, id);
- IF TraceInstantiate IN Trace THEN
- KernelLog.String("Repositories.Registry.InstantiateElement: Instantiate component: "); KernelLog.String(componentName); KernelLog.Ln;
- KernelLog.Boolean(element # NIL); KernelLog.Ln;
- END;
- END;
- ELSE
- KernelLog.String("Wrong name: "); KernelLog.String(name); KernelLog.Ln;
- END;
- RETURN element;
- END InstantiateElement;
- PROCEDURE InstantiateLate*(e: XML.Element): XML.Element;
- VAR generator: XML.String; element: XML.Element;
- moduleName, procedureName : Modules.Name; msg : ARRAY 128 OF CHAR; res : WORD;
- generate : XML.GeneratorProcedure;
- a: XML.Attribute;
- enumerator: XMLObjects.Enumerator;
- ptr: ANY;
- BEGIN
- element := NIL;
- generator := e.GetAttributeValue("generator");
- IF generator # NIL THEN
- IF TraceInstantiate IN Trace THEN KernelLog.String("Repositories.Registry.InstantiateElementLate:"); KernelLog.String(generator^); KernelLog.Ln; END;
- Commands.Split(generator^, moduleName, procedureName, res, msg);
- IF (res = Commands.Ok) THEN
- GETPROCEDURE(moduleName, procedureName, generate);
- IF (generate # NIL) THEN
- element := generate();
- ELSE
- KernelLog.String("Generator procedure not found: ");
- KernelLog.String(moduleName); KernelLog.Char("."); KernelLog.String(procedureName); KernelLog.Ln;
- END;
- ELSE
- KernelLog.String("Invalid generator name"); KernelLog.Ln;
- END;
- END;
- IF (element # NIL) THEN
- enumerator := e.GetAttributes();
- WHILE enumerator.HasMoreElements() DO
- ptr := enumerator.GetNext();
- IF (ptr IS XML.Attribute) THEN
- (*! element must be copied ..., how to avoid this ? *)
- element.SetAttributeValue(ptr(XML.Attribute).GetName()^, ptr(XML.Attribute).GetValue()^);
- (* element.AddAttribute(ptr(XML.Attribute)); *)
- END;
- END;
- RETURN element;
- ELSE
- RETURN e;
- END;
- END InstantiateLate;
- END Registry;
- TYPE
- ErrorReporter = OBJECT
- VAR
- nofErrors : LONGINT;
- PROCEDURE &Reset;
- BEGIN
- nofErrors := 0;
- END Reset;
- PROCEDURE Report(pos, line, col: LONGINT; CONST msg: ARRAY OF CHAR);
- BEGIN
- INC(nofErrors);
- KernelLog.Enter; KernelLog.Char(CHR(9H)); KernelLog.Char(CHR(9H)); KernelLog.String("pos "); KernelLog.Int(pos, 6);
- KernelLog.String(", line "); KernelLog.Int(line, 0); KernelLog.String(", column "); KernelLog.Int(col, 0);
- KernelLog.String(" "); KernelLog.String(msg); KernelLog.Exit;
- END Report;
- END ErrorReporter;
- VAR
- registry- : Registry;
- indexRegistry : IndexRegistry;
- repositories : Repository;
- globalTimestamp : LONGINT;
- StrNoName,
- StrRepository, StrComponent, StrApplication, StrDictionary : Strings.String;
- (* Set Locked flag for <component> and all its children *)
- PROCEDURE SetLockedFlag(component : Component; locked : BOOLEAN);
- VAR c : XML.Content;
- BEGIN
- ASSERT(component # NIL);
- IF locked THEN INCL(component.flags, Locked); ELSE EXCL(component.flags, Locked); END;
- c := component.GetFirst();
- WHILE (c # NIL) DO
- IF (c IS Component) THEN SetLockedFlag(c(Component), locked); END;
- c := component.GetNext(c);
- END;
- END SetLockedFlag;
- PROCEDURE LockChildren(component : Component);
- VAR c : XML.Content;
- BEGIN
- ASSERT(component # NIL);
- c := component.GetFirst();
- WHILE (c # NIL) DO
- IF (c IS Component) THEN SetLockedFlag(c(Component), TRUE); END;
- c := component.GetNext(c);
- END;
- END LockChildren;
- PROCEDURE GenerateComponent*(CONST generator : ARRAY OF CHAR) : Component;
- VAR
- moduleName, procedureName : Modules.Name; msg : ARRAY 128 OF CHAR; res : WORD;
- generate : XML.GeneratorProcedure;
- element : XML.Element;
- BEGIN
- element := NIL;
- Commands.Split(generator, moduleName, procedureName, res, msg);
- IF (res = Commands.Ok) THEN
- GETPROCEDURE(moduleName, procedureName, generate);
- IF (generate # NIL) THEN
- element := generate();
- ELSE
- KernelLog.String("Generator procedure not found: ");
- KernelLog.String(moduleName); KernelLog.Char("."); KernelLog.String(procedureName); KernelLog.Ln;
- END;
- ELSE
- KernelLog.String("Invalid generator name"); KernelLog.Ln;
- END;
- IF (element # NIL) THEN
- RETURN element (Component);
- ELSE
- RETURN NIL;
- END;
- END GenerateComponent;
- PROCEDURE FindChild(parent : XML.Element; CONST elementName : ARRAY OF CHAR) : XML.Element;
- VAR enum : XMLObjects.Enumerator; ptr : ANY; name : Strings.String;
- BEGIN
- ASSERT(parent # NIL);
- enum := parent.GetContents();
- WHILE enum.HasMoreElements() DO
- ptr := enum.GetNext();
- IF (ptr # NIL) & (ptr IS XML.Element) THEN
- name := ptr(XML.Element).GetName();
- IF (name # NIL) & (name^ = elementName) THEN
- RETURN ptr (XML.Element);
- END;
- END;
- END;
- RETURN NIL;
- END FindChild;
- PROCEDURE IncrementTimestamp*(VAR timestamp : LONGINT);
- BEGIN {EXCLUSIVE}
- INC(timestamp);
- INC(globalTimestamp);
- END IncrementTimestamp;
- PROCEDURE GetTimestamp*() : LONGINT;
- BEGIN
- RETURN globalTimestamp;
- END GetTimestamp;
- PROCEDURE AwaitChange*(VAR curTimestamp : LONGINT);
- BEGIN {EXCLUSIVE}
- AWAIT(curTimestamp # globalTimestamp);
- curTimestamp := globalTimestamp;
- END AwaitChange;
- PROCEDURE IsXmlFilename(string : ARRAY OF CHAR) : BOOLEAN;
- BEGIN
- Strings.LowerCase(string);
- RETURN Strings.Match("*.xml", string);
- END IsXmlFilename;
- PROCEDURE Parse(reader : Streams.Reader; elemReg : XML.ElementRegistry; errors : ErrorReporter) : XML.Element;
- VAR scanner : XMLScanner.Scanner; parser : XMLParser.Parser; document : XML.Document;
- BEGIN
- ASSERT((reader # NIL) & (errors # NIL));
- NEW(scanner, reader);
- (* scanner.SetStringPooling({0..31}); *)
- NEW(parser, scanner);
- parser.elemReg := elemReg;
- parser.reportError := errors.Report;
- document := parser.Parse();
- IF (document # NIL) THEN
- RETURN document.GetRoot();
- ELSE
- RETURN NIL;
- END;
- END Parse;
- PROCEDURE GetWriter(archive : Archives.Archive; CONST filename : ARRAY OF CHAR) : Streams.Writer;
- VAR writer : Streams.Writer; sender : Streams.Sender;
- BEGIN (* must hold archive lock!! *)
- sender := archive.OpenSender(filename);
- IF (sender # NIL) THEN
- NEW(writer, sender, 4096);
- ELSE
- writer := NIL;
- END;
- RETURN writer;
- END GetWriter;
- PROCEDURE SplitName*(CONST name : ARRAY OF CHAR; VAR repositoryName, componentName : ARRAY OF CHAR; VAR id : LONGINT) : BOOLEAN;
- VAR count, pos, next : LONGINT; succeeded : BOOLEAN;
- BEGIN
- succeeded := TRUE;
- count := Strings.Count (name, Delimiter);
- IF (count = 0) THEN
- repositoryName := ""; COPY(name, componentName); id := 0;
- ELSIF (count = 1) THEN
- next := Strings.Find(name, 0, Delimiter);
- Strings.Copy(name, 0, next, repositoryName);
- Strings.Copy(name, next + 1, Strings.Length(name) - next, componentName);
- id := 0;
- succeeded := ((repositoryName = "" ) OR IsValidName(repositoryName)) & IsValidName(componentName);
- (* no, this is ambiguous, rather use ":ComponenName:Number" for such cases
- IF ~succeeded & IsValidName(repositoryName) & IsNumber(componentName) THEN
- succeeded := TRUE;
- Strings.StrToInt(componentName, id);
- D.String("split name with index"); D.String(repositoryName); D.String(" : "); D.Int(id,1); D.Ln;
- COPY(repositoryName, componentName);
- repositoryName := "";
- END;
- *)
- ELSIF (count = 2) THEN
- next := Strings.Find(name, 0, Delimiter);
- Strings.Copy(name, 0, next, repositoryName);
- pos := next + 1;
- next := Strings.Find(name, pos, Delimiter);
- Strings.Copy(name, pos, next - pos, componentName);
- pos := next + 1;
- Strings.StrToIntPos(name, id, pos);
- succeeded := ((repositoryName = "") OR IsValidName(repositoryName)) & IsValidName(componentName);
- ELSE
- succeeded := FALSE;
- END;
- RETURN succeeded;
- END SplitName;
- PROCEDURE JoinName*(CONST repositoryName, componentName : ARRAY OF CHAR; id : LONGINT; VAR name : ARRAY OF CHAR);
- VAR nbrStr : ARRAY 16 OF CHAR;
- BEGIN
- COPY(repositoryName, name);
- Strings.Append(name, Delimiter);
- Strings.Append(name, componentName);
- IF (id # 0) THEN
- Strings.Append(name, Delimiter);
- Strings.IntToStr(id, nbrStr);
- Strings.Append(name, nbrStr);
- END;
- END JoinName;
- (** valid name: Starts with latin letter, contains only latin letter and arabic number *)
- PROCEDURE IsValidName*(CONST name : ARRAY OF CHAR) : BOOLEAN;
- VAR valid : BOOLEAN; i : LONGINT;
- BEGIN
- valid := (("A" <= CAP(name[0])) & (CAP(name[0]) <= "Z"));
- IF valid THEN
- i := 0;
- WHILE valid & (i < LEN(name)) & (name[i] # 0X) DO
- valid := (("A" <= CAP(name[i])) & (CAP(name[i]) <= "Z")) OR (("0" <= name[i]) & (name[i] <= "9"));
- INC(i);
- END;
- valid := (i < LEN(name)) & (name[i] = 0X);
- END;
- RETURN valid;
- END IsValidName;
- PROCEDURE IsNumber*(CONST name: ARRAY OF CHAR): BOOLEAN;
- VAR i: LONGINT;
- BEGIN
- i := 0;
- WHILE (i<LEN(name)) & (name[i] # 0X) & ('0' <= name[i]) & (name[i] <= '9') DO
- INC(i);
- END;
- RETURN (i<LEN(name)) & (name[i] = 0X)
- END IsNumber;
- PROCEDURE NewJoinName*(CONST repositoryName, componentName : ARRAY OF CHAR; id : LONGINT) : Strings.String;
- VAR name : ARRAY 256 OF CHAR;
- BEGIN
- JoinName(repositoryName, componentName, id, name);
- RETURN Strings.NewString(name);
- END NewJoinName;
- PROCEDURE SplitFilename(CONST fullname : ARRAY OF CHAR; VAR repositoryName, extension : ARRAY OF CHAR);
- VAR name, path : Files.FileName;
- BEGIN
- Files.SplitPath(fullname, path, name);
- Files.SplitExtension(name, repositoryName, extension);
- END SplitFilename;
- PROCEDURE GetCommand*(CONST command : ARRAY OF CHAR; VAR res : WORD) : Command;
- VAR proc : Command; moduleName, procedureName : Modules.Name; msg : ARRAY 128 OF CHAR;
- BEGIN
- proc := NIL;
- Commands.Split(command, moduleName, procedureName, res, msg);
- IF (res = Commands.Ok) THEN
- GETPROCEDURE(moduleName, procedureName, proc);
- IF (proc # NIL) THEN
- res := Ok;
- ELSE
- res := NotFound;
- KernelLog.String("Repositories.GetCommand: "); KernelLog.String(command);
- KernelLog.String(" not found"); KernelLog.Ln;
- END;
- ELSE
- KernelLog.String("Repositories.GetCommand: "); KernelLog.String(command);
- KernelLog.String(" is not a valid command string, res: "); KernelLog.Int(res, 0); KernelLog.Ln;
- END;
- RETURN proc;
- END GetCommand;
- PROCEDURE IsCommandString*(CONST string : ARRAY OF CHAR) : BOOLEAN;
- BEGIN
- RETURN Strings.StartsWith2(CommandPrefix, string);
- END IsCommandString;
- PROCEDURE ExtractCommand*(CONST string : ARRAY OF CHAR; VAR command : ARRAY OF CHAR);
- BEGIN
- IF IsCommandString(string) THEN
- COPY(string, command);
- Strings.Delete(command, 0, Strings.Length(CommandPrefix));
- ELSE
- command := "";
- END;
- END ExtractCommand;
- PROCEDURE CallCommand*(CONST command : ARRAY OF CHAR; VAR context : Context; VAR res : WORD);
- VAR
- cmd : ARRAY 64 OF CHAR; param : POINTER TO ARRAY OF CHAR; reader : Streams.StringReader;
- proc : Command; i, j : LONGINT; object: ANY;
- BEGIN
- IF Strings.StartsWith2(CommandPrefix, command) THEN
- i := Strings.Length(CommandPrefix);
- ELSE
- i := 0;
- END;
- WHILE (i < LEN(command)) & (command[i] # 0X) & (command[i] <= " ") DO INC(i); END;
- j := 0;
- WHILE (j < LEN(cmd)) & (i < LEN(command)) & (command[i] > " ") DO
- cmd[j] := command[i];
- INC(i); INC(j);
- END;
- IF (j < LEN(cmd)) & (i < LEN(command)) & (j >= 2) (* M.P *) THEN
- cmd[j] := 0X;
- proc := GetCommand(cmd, res);
- IF (res = Ok) THEN
- WHILE (i < LEN(command)) & (command[i] # 0X) & (command[i] <= " ") DO INC(i); END;
- IF (i < Strings.Length(command)) THEN
- NEW(param, Strings.Length(command) - i + 1);
- j := 0;
- WHILE (i < LEN(command)) & (command[i] # 0X) DO param[j] := command[i]; INC(i); INC(j); END;
- param[j] := 0X;
- NEW(reader, Strings.Length(command));
- reader.Set(param^);
- ELSE
- reader := NIL;
- END;
- IF (context = NIL) THEN NEW(context, NIL, reader, NIL, NIL, NIL);
- ELSE
- context.Init(context.in, reader, context.out, context.error, context.caller);
- END;
- proc(context);
- ELSE
- object := GenerateComponent(cmd);
- IF object # NIL THEN
- IF (context = NIL) THEN NEW(context, NIL, reader, NIL, NIL, NIL);
- ELSE
- context.Init(context.in, reader, context.out, context.error, context.caller);
- END;
- context.object := object
- END;
- END;
- ELSE
- res := NotFound;
- END;
- END CallCommand;
- PROCEDURE GetTranslationInfo*(CONST string : ARRAY OF CHAR; VAR dictionary : Dictionary; VAR word : Strings.String; VAR res : WORD);
- VAR repositoryName, dictionaryName, temp : ARRAY 512 OF CHAR; i, j : LONGINT;
- BEGIN
- res := Ok;
- dictionary := NIL; word := NIL;
- IF (LEN(string) > 7) THEN
- (** "::" + LibraryName + ":" + DictionaryName + ":" + DictionaryWord *)
- IF (string[0] = ":") & (string[1] = ":") THEN
- i := 2; j := 0;
- WHILE (i < LEN(string)) & (j < LEN(repositoryName) - 1) & (string[i] # 0X) & (string[i] # ":") DO
- repositoryName[j] := string[i];
- INC(i); INC(j);
- END;
- repositoryName[j] := 0X;
- IF (i < LEN(string)) & (string[i] = ":") THEN
- INC(i); j := 0;
- WHILE (i < LEN(string)) & (j < LEN(dictionaryName) - 1) & (string[i] # 0X) & (string[i] # ":") DO
- dictionaryName[j] := string[i];
- INC(i); INC(j);
- END;
- dictionaryName[j] := 0X;
- IF (i < LEN(string)) & (string[i] = ":") THEN
- INC(i); j := 0;
- WHILE(i < LEN(string)) & (j < LEN(temp) - 1) & (string[i] # 0X) DO
- temp[j] := string[i];
- INC(i); INC(j);
- END;
- temp[j] := 0X;
- IF (i < LEN(string)) & (string[i] = 0X) THEN
- word := Strings.NewString(temp);
- GetDictionary(repositoryName, dictionaryName, dictionary, res);
- IF (res # Ok) THEN
- KernelLog.String("Repositories.GetTranlationInfo: Warning: Dictionary ");
- KernelLog.String(repositoryName); KernelLog.String(":"); KernelLog.String(dictionaryName);
- KernelLog.String(" not found, res: "); KernelLog.Int(res, 0); KernelLog.Ln;
- END;
- END;
- END;
- END;
- END;
- END;
- END GetTranslationInfo;
- PROCEDURE Translate*(CONST string : ARRAY OF CHAR; languages : Localization.Languages) : Strings.String;
- VAR dictionary : Dictionary; word, translation : Strings.String; res : WORD;
- BEGIN
- ASSERT(languages # NIL);
- GetTranslationInfo(string, dictionary, word, res);
- IF (res = Ok) & (dictionary # NIL) & (word # NIL) THEN
- translation := dictionary.Translate(word, languages);
- ELSE
- translation := Strings.NewString(string);
- END;
- ASSERT(translation # NIL);
- RETURN translation;
- END Translate;
- PROCEDURE GetDictionary*(CONST repositoryName, dictionaryName : ARRAY OF CHAR; VAR dictionary : Dictionary; VAR res : WORD);
- VAR repository : Repository;
- BEGIN
- dictionary := NIL;
- repository := ThisRepository(repositoryName);
- IF (repository # NIL) THEN
- dictionary := repository.GetDictionary(dictionaryName);
- IF (dictionary # NIL) THEN
- res := Ok;
- ELSE
- res := DictionaryNotFound;
- END;
- ELSE
- res := RepositoryNotFound;
- END;
- END GetDictionary;
- PROCEDURE GetDictionaryByString*(CONST string : ARRAY OF CHAR; VAR dictionary : Dictionary; VAR res : WORD);
- VAR repositoryName : Files.FileName; dictionaryName : ARRAY 128 OF CHAR; ignoreID : LONGINT;
- BEGIN
- IF SplitName(string, repositoryName, dictionaryName, ignoreID) THEN
- GetDictionary(repositoryName, dictionaryName, dictionary, res);
- ELSE
- res := FormatError;
- END;
- END GetDictionaryByString;
- PROCEDURE GetComponent*(CONST repositoryName, componentName : ARRAY OF CHAR; refNum : LONGINT; VAR component : Component; VAR res : WORD);
- VAR repository : Repository;
- BEGIN
- component := NIL;
- repository := ThisRepository(repositoryName);
- IF (repository # NIL) THEN
- component := repository.GetComponent(componentName, refNum);
- IF (component # NIL) THEN
- res := Ok;
- ELSE
- res := ComponentNotFound;
- END;
- ELSE
- res := RepositoryNotFound;
- END;
- END GetComponent;
- PROCEDURE GetComponentByString*(CONST string : ARRAY OF CHAR; VAR component : Component; VAR res : WORD);
- VAR repositoryName : Files.FileName; componentName : ARRAY 128 OF CHAR; componentID : LONGINT;
- BEGIN
- IF SplitName(string, repositoryName, componentName, componentID) THEN
- GetComponent(repositoryName, componentName, componentID, component, res);
- ELSE
- res := FormatError;
- END;
- END GetComponentByString;
- PROCEDURE PutComponent*(component : Component; CONST repositoryName, componentName : ARRAY OF CHAR; VAR id : LONGINT; VAR res : WORD);
- VAR repository : Repository;
- BEGIN
- ASSERT(component # NIL);
- repository := ThisRepository(repositoryName);
- IF (repository # NIL) THEN
- repository.PutComponent(component, componentName, id, res);
- ELSE
- res := RepositoryNotFound;
- END;
- END PutComponent;
- PROCEDURE UnbindComponent*(CONST repositoryName, componentName : ARRAY OF CHAR; refNum : LONGINT; VAR res : WORD);
- VAR repository : Repository;
- BEGIN
- repository := ThisRepository(repositoryName);
- IF (repository # NIL) THEN
- repository.UnbindComponent(componentName, refNum, res);
- ELSE
- res := RepositoryNotFound;
- END;
- END UnbindComponent;
- PROCEDURE RemoveComponent*(CONST repositoryName, componentName : ARRAY OF CHAR; refNum : LONGINT; VAR res : WORD);
- VAR repository : Repository;
- BEGIN
- repository := ThisRepository(repositoryName);
- IF (repository # NIL) THEN
- repository.RemoveComponent(componentName, refNum, res);
- ELSE
- res := RepositoryNotFound;
- END;
- END RemoveComponent;
- (* Append repository to global list of repositories *)
- PROCEDURE Add(repository : Repository; VAR res : WORD);
- VAR r : Repository;
- BEGIN (* {EXCLUSIVE} *)
- ASSERT(repository # NIL);
- r := FindRepository(repository.name);
- IF (r = NIL) THEN
- IF (repositories = NIL) THEN
- repositories := repository;
- ELSE
- r := repositories;
- WHILE (r.next # NIL) DO r := r.next; END;
- r.next := repository;
- END;
- INC(globalTimestamp);
- res := Ok;
- ELSE
- res := DuplicateRepository;
- END;
- END Add;
- (* Remove repository from global list of repositories *)
- PROCEDURE Remove(repository : Repository; VAR res : WORD);
- VAR r : Repository;
- BEGIN (* {EXCLUSIVE} *)
- ASSERT(repository # NIL);
- IF (repositories = repository) THEN
- repositories := repository.next;
- res := Ok;
- ELSE
- r := repositories;
- WHILE (r # NIL) & (r.next # repository) DO r := r.next; END;
- IF (r # NIL) THEN
- r.next := r.next.next;
- res := Ok;
- ELSE
- res := RepositoryNotFound;
- END;
- END;
- IF (res = Ok) THEN INC(globalTimestamp); END;
- END Remove;
- (* Find a loaded repository by name *)
- PROCEDURE FindRepository(CONST name : ARRAY OF CHAR) : Repository;
- VAR r : Repository;
- BEGIN
- r := repositories;
- WHILE (r # NIL) & (r.name # name) DO r := r.next; END;
- RETURN r;
- END FindRepository;
- (** Retrieve a repository be name *)
- PROCEDURE ThisRepository*(CONST name : ARRAY OF CHAR) : Repository;
- VAR r : Repository; res : WORD;
- BEGIN {EXCLUSIVE}
- r := FindRepository(name);
- IF (r = NIL) THEN
- r := LoadRepository(name, res);
- END;
- RETURN r;
- END ThisRepository;
- (** Retrieve all currently loaded repositories *)
- PROCEDURE GetAll*(VAR reps : Repositories);
- VAR
- r : Repository;
- nofRepositories, i : LONGINT;
- PROCEDURE GetNofRepositories() : LONGINT;
- VAR r : Repository; nofRepositories : LONGINT;
- BEGIN
- nofRepositories := 0;
- r := repositories;
- WHILE (r # NIL) DO INC(nofRepositories); r := r.next; END;
- RETURN nofRepositories;
- END GetNofRepositories;
- BEGIN {EXCLUSIVE}
- nofRepositories := GetNofRepositories();
- IF (nofRepositories > 0) THEN
- IF (reps = NIL) OR (LEN(reps) < nofRepositories) THEN NEW(reps, nofRepositories); END;
- r := repositories; i := 0;
- WHILE (i < LEN(reps)) DO
- reps[i] := r;
- IF (r # NIL) THEN r := r.next; END;
- INC(i);
- END;
- ELSE
- IF (reps # NIL) THEN
- FOR i := 0 TO LEN(reps)-1 DO reps[i] := NIL; END;
- END;
- END;
- END GetAll;
- (* Load a repository *)
- PROCEDURE LoadRepository(CONST name : ARRAY OF CHAR; VAR res : WORD) : Repository;
- VAR
- filename : Files.FileName;
- repository : Repository;
- archive : Archives.Archive;
- receiver : Streams.Receiver; reader : Streams.Reader;
- element : XML.Element;
- ignore : WORD;
- errors : ErrorReporter;
- file: Files.File; writer: Files.Writer; freader: Files.Reader; ch: CHAR; buf: ARRAY 512 OF CHAR; len: LONGINT;
- BEGIN (* {EXCLUSIVE} *)
- ASSERT(FindRepository(name) = NIL);
- COPY(name, filename);
- Strings.Append(filename, "."); Strings.Append(filename, DefaultFileExtension);
- IF TraceLoading IN Trace THEN KernelLog.String("Repositories.LoadRepository: "); KernelLog.String(filename); KernelLog.String(" ... "); END;
- repository := NIL;
- archive := Archives.Old(filename, "tar");
- IF (archive # NIL) THEN
- IF TraceLoading IN Trace THEN KernelLog.String("archive found ... "); END;
- archive.Acquire;
- receiver := archive.OpenReceiver(IndexFile);
- archive.Release;
- IF (receiver # NIL) THEN
- NEW(reader, receiver, 4096);
- (*
- file := Files.New("");
- Files.OpenWriter(writer, file, 0);
- REPEAT
- reader.Bytes(buf, 0, LEN(buf), len); writer.Bytes(buf, 0, len);
- UNTIL reader.res # 0;
- writer.Update;
- Files.OpenReader(freader, file,0);
- reader := freader;
- *)
- IF TraceLoading IN Trace THEN KernelLog.String("index file found ... "); END;
- (*NEW(reader, receiver, 4096);*)
- NEW(errors);
- element := Parse(reader, indexRegistry, errors);
- IF (element # NIL) & (element IS Repository) THEN
- repository := element (Repository);
- repository.archive := archive;
- COPY(name, repository.name);
- COPY(filename, repository.filename);
- ignore := repository.Initialize();
- END;
- IF (repository # NIL) THEN
- IF TraceLoading IN Trace THEN KernelLog.String("index file parsed... "); END;
- Add(repository, res);
- END;
- ELSE
- res := FormatError;
- END;
- ELSE
- res := RepositoryNotFound;
- END;
- IF TraceLoading IN Trace THEN KernelLog.Int(res, 0); KernelLog.Ln; END;
- RETURN repository;
- END LoadRepository;
- (** Unload a currently loaded repository *)
- PROCEDURE UnloadRepository*(CONST name : ARRAY OF CHAR; VAR res : WORD);
- VAR repository : Repository;
- BEGIN {EXCLUSIVE}
- repository := FindRepository(name);
- IF (repository # NIL) THEN
- Remove(repository, res);
- ELSE
- res := RepositoryNotLoaded;
- END;
- END UnloadRepository;
- (** Store the current state of a currenlty loaded repository *)
- PROCEDURE StoreRepository*(CONST name : ARRAY OF CHAR; VAR res : WORD);
- VAR repository : Repository;
- BEGIN {EXCLUSIVE}
- repository := FindRepository(name);
- IF (repository # NIL) THEN
- repository.Store(res);
- INC(globalTimestamp);
- ELSE
- res := RepositoryNotLoaded;
- END;
- END StoreRepository;
- (** Create an empty new repository.
- The repository name is derived from the filename (repository name = filename without extension)
- The repository is not loaded upon creation *)
- PROCEDURE CreateRepository*(CONST filename : ARRAY OF CHAR; VAR res : WORD);
- VAR
- repository : Repository;
- archive : Archives.Archive;
- sender : Streams.Sender; writer : Streams.Writer;
- extension : ARRAY 16 OF CHAR;
- PROCEDURE AddHeader(parent : XML.Element);
- VAR header, element : XML.Element; charArray : XML.ArrayChars;
- BEGIN
- ASSERT(parent # NIL);
- NEW(header); header.SetName("Header");
- parent.AddContent(header);
- NEW(element); element.SetName("Version");
- header.AddContent(element);
- NEW(charArray); charArray.SetStr("1");
- element.AddContent(charArray);
- NEW(element); element.SetName("Public");
- header.AddContent(element);
- NEW(charArray); charArray.SetStr("FALSE");
- element.AddContent(charArray);
- END AddHeader;
- PROCEDURE AddStructure(parent : XML.Element);
- VAR element : XML.Element;
- BEGIN
- ASSERT(parent # NIL);
- NEW(element); element.SetName("Applications"); parent.AddContent(element);
- NEW(element); element.SetName("Components"); parent.AddContent(element);
- NEW(element); element.SetName("Dictionaries"); parent.AddContent(element);
- END AddStructure;
- BEGIN
- IF TraceCreation IN Trace THEN KernelLog.String("Repositories.CreateRepository "); KernelLog.String(filename); KernelLog.String(" ... "); END;
- archive := Archives.New(filename, "tar");
- IF (archive # NIL) THEN
- archive.Acquire;
- sender := archive.OpenSender(IndexFile);
- archive.Release;
- IF (sender # NIL) THEN
- NEW(writer, sender, 4096);
- NEW(repository);
- SplitFilename(filename, repository.name, extension);
- COPY(filename, repository.filename);
- repository.archive := archive;
- AddHeader(repository);
- AddStructure(repository);
- writer.String('<?xml version="1.0" encoding="UTF-8" standalone="yes"?>'); writer.Ln;
- repository.Write(writer, NIL, 0);
- writer.Update;
- res := Ok;
- ELSE
- res := ArchivesError;
- END;
- ELSE
- res := CannotCreateArchive;
- END;
- IF TraceCreation IN Trace THEN KernelLog.String("res = "); KernelLog.Int(res, 0); KernelLog.Ln; END;
- END CreateRepository;
- (*
- PROCEDURE FromXMLInRepository*(xml: XML.Element; repository: Repository);
- VAR generator: PROCEDURE(): XML.Element;
- VAR
- l,name: Strings.String;
- moduleName, procedureName: Modules.Name;
- res: WORD; msg: ARRAY 32 OF CHAR;
- component: Component;
- element: XML.Element;
- BEGIN
- component := NIL;
- IF xml # NIL THEN
- name := xml.GetName();
- l := xml.GetAttributeValue("generator");
- IF l # NIL THEN
- Commands.Split(l^, moduleName, procedureName, res, msg);
- IF (res = Commands.Ok) THEN
- GETPROCEDURE(moduleName, procedureName, generator);
- IF (generator # NIL) THEN
- element := generator();
- IF (element # NIL) & (element IS Component) THEN
- component := element(Component);
- component.SetName(name^);
- component.FromXMLInRepository(xml,repository);
- END;
- ELSE KernelLog.String("WMComponents error: invalid generator "); KernelLog.String(l^); KernelLog.Ln;
- END;
- ELSE KernelLog.String("WMComponents error: could not generate component "); KernelLog.String(l^); KernelLog.Ln;
- END;
- ELSE
- l := xml.GetAttributeValue("reference");
- IF l # NIL THEN
- repository.GetComponent(l^);
- END;
- END;
- RETURN component
- END FromXMLInRepository;
- *)
- PROCEDURE ComponentFromXML*(xml: XML.Element): Component;
- VAR generator: PROCEDURE(): XML.Element;
- VAR
- l,name: Strings.String;
- moduleName, procedureName: Modules.Name;
- res: WORD; msg: ARRAY 32 OF CHAR;
- component: Component;
- element: XML.Element;
- BEGIN
- component := NIL;
- IF xml # NIL THEN
- name := xml.GetName();
- l := xml.GetAttributeValue("generator");
- IF l # NIL THEN
- Commands.Split(l^, moduleName, procedureName, res, msg);
- IF (res = Commands.Ok) THEN
- GETPROCEDURE(moduleName, procedureName, generator);
- IF (generator # NIL) THEN
- element := generator();
- IF (element # NIL) & (element IS Component) THEN
- component := element(Component);
- component.SetName(name^);
- component.FromXML(xml);
- END;
- ELSE KernelLog.String("WMComponents error: invalid generator "); KernelLog.String(l^); KernelLog.Ln;
- END;
- ELSE KernelLog.String("WMComponents error: could not generate component "); KernelLog.String(l^); KernelLog.Ln;
- END;
- END;
- END;
- RETURN component
- END ComponentFromXML;
- PROCEDURE ShowRes*(res : WORD; out : Streams.Writer);
- BEGIN
- ASSERT(out # NIL);
- out.String("res: "); out.Int(res, 0);
- out.String(" (");
- CASE res OF
- |Ok: out.String("Ok");
- |NotFound: out.String("Not found");
- |RepositoryNotFound: out.String("Repository not found");
- |ComponentNotFound: out.String("Component not found");
- |RepositoryNotLoaded: out.String("Repository not loaded");
- |DuplicateName: out.String("Duplicate name");
- |DuplicateID: out.String("Duplicate ID");
- |DuplicateRepository: out.String("Duplicate repository");
- |IndexError: out.String("Index error");
- |CannotCreateArchive: out.String("Cannot create archive");
- |ArchivesError: out.String("Archive error");
- |WrongVersion: out.String("Wrong version");
- |FormatError: out.String("Format error");
- ELSE
- out.String("Unknown");
- END;
- out.String(")");
- END ShowRes;
- (** Create an empty repository *)
- PROCEDURE Create*(context : Commands.Context); (** repositoryName ~ *)
- VAR repositoryName : Files.FileName; res : WORD;
- BEGIN
- context.arg.SkipWhitespace; context.arg.String(repositoryName);
- context.out.String("Creating repository '"); context.out.String(repositoryName); context.out.String("' ... ");
- context.out.Update;
- CreateRepository(repositoryName, res);
- IF (res = Ok) THEN
- context.out.String("done.");
- ELSE
- context.out.String("not done, "); ShowRes(res, context.out);
- END;
- context.out.Ln;
- END Create;
- PROCEDURE Store*(context : Commands.Context); (** repositoryName ~ *)
- VAR repositoryName : Files.FileName; res : WORD;
- BEGIN
- context.arg.SkipWhitespace; context.arg.String(repositoryName);
- context.out.String("Storing repository '"); context.out.String(repositoryName); context.out.String("' ... "); context.out.Update;
- StoreRepository(repositoryName, res);
- IF (res = Ok) THEN
- context.out.String("done.");
- ELSE
- context.out.String("not done, "); ShowRes(res, context.out);
- END;
- context.out.Ln;
- END Store;
- PROCEDURE Load*(context : Commands.Context); (** filename ~ *)
- VAR repository : Repository; filename : Files.FileName;
- BEGIN
- context.arg.SkipWhitespace; context.arg.String(filename);
- context.out.String("Loading repository '"); context.out.String(filename); context.out.String("' ... ");
- repository := ThisRepository(filename);
- IF (repository # NIL) THEN
- context.out.String("done.");
- ELSE
- context.out.String("repository not found.");
- END;
- context.out.Ln;
- END Load;
- PROCEDURE Unload*(context : Commands.Context); (** repositoryName ~ *)
- VAR repositoryName : Files.FileName; res : WORD;
- BEGIN
- context.arg.SkipWhitespace; context.arg.String(repositoryName);
- context.out.String("Unloaded repository '"); context.out.String(repositoryName); context.out.String("' ... "); context.out.Update;
- UnloadRepository(repositoryName, res);
- IF (res = Ok) THEN
- context.out.String("done.");
- ELSE
- context.out.String("not done, "); ShowRes(res, context.out);
- END;
- context.out.Ln;
- END Unload;
- (** Put component into repository *)
- PROCEDURE Put*(context : Commands.Context); (** componentName repositoryName asName [zeroID] ~ *)
- VAR
- componentName, repositoryName, asName : ARRAY 256 OF CHAR;
- nbr : ARRAY 3 OF CHAR;
- component : Component; id : LONGINT; res: WORD;
- BEGIN
- context.arg.SkipWhitespace; context.arg.String(componentName);
- context.arg.SkipWhitespace; context.arg.String(repositoryName);
- context.arg.SkipWhitespace; context.arg.String(asName);
- context.arg.SkipWhitespace; context.arg.String(nbr);
- IF (nbr = "0") THEN id := 0; ELSE id := -1; END;
- context.out.String("Put component '"); context.out.String(componentName);
- context.out.String("' to repository '"); context.out.String(repositoryName); context.out.String("' as '");
- context.out.String(asName); context.out.String("' ... ");
- context.out.Update;
- GetComponentByString(componentName, component, res);
- IF (res = Ok) & (component # NIL) THEN
- PutComponent(component, repositoryName, asName, id, res);
- IF (res = Ok) THEN
- context.out.String("done.");
- ELSE
- context.out.String("not done, "); ShowRes(res, context.out);
- END;
- ELSE
- context.out.String("component loading error, "); ShowRes(res, context.out);
- END;
- context.out.Ln;
- END Put;
- PROCEDURE Dump*(context : Commands.Context); (** filename ~ *)
- VAR repository : Repository; filename : Files.FileName;
- BEGIN
- context.arg.SkipWhitespace; context.arg.String(filename);
- context.out.String("Dump of repository '"); context.out.String(filename); context.out.String("': ");
- context.out.Ln; context.out.Update;
- repository := ThisRepository(filename);
- IF (repository # NIL) THEN
- repository.Dump(context.out);
- ELSE
- context.out.String("Repository not found.");
- END;
- context.out.Ln;
- END Dump;
- PROCEDURE DumpAll*(context : Commands.Context); (** ~ *)
- VAR repositories : Repositories; count, i : LONGINT;
- BEGIN
- context.out.String("Currently loaded repositories: "); context.out.Ln;
- GetAll(repositories);
- IF (repositories # NIL) THEN
- count := 0;
- FOR i := 0 TO LEN(repositories) - 1 DO
- IF (repositories[i] # NIL) THEN
- INC(count);
- repositories[i].Dump(context.out);
- END;
- END;
- context.out.Int(count, 0); context.out.String(" repositories loaded.");
- ELSE
- context.out.String("none");
- END;
- context.out.Ln;
- END DumpAll;
- PROCEDURE Call*(context : Commands.Context); (** moduleName.procedureName [params] ~ *)
- VAR c : Context; cmdString : POINTER TO ARRAY OF CHAR; res : WORD; ignore: LONGINT;
- BEGIN
- NEW(c, NIL, NIL, context.out, context.error, context.caller);
- IF (context.arg.Available() > 0) THEN
- NEW(cmdString, context.arg.Available());
- context.arg.Bytes(cmdString^, 0, LEN(cmdString), ignore);
- CallCommand(cmdString^, c, res);
- context.out.String("res: "); context.out.Int(res, 0); context.out.Ln;
- context.out.String("c.res: "); context.out.Int(c.result, 0); context.out.Ln;
- context.out.String("c.object: ");
- IF (c.object = NIL) THEN context.out.String("NIL"); ELSE context.out.String("Present"); END;
- context.out.Ln;
- ELSE
- context.error.String("Missing arguments"); context.error.Ln;
- END;
- END Call;
- PROCEDURE InitStrings;
- BEGIN
- StrNoName := Strings.NewString("NoName");
- StrRepository := Strings.NewString(XmlRepository);
- StrComponent := Strings.NewString(XmlComponent);
- StrApplication := Strings.NewString(XmlApplication);
- StrDictionary := Strings.NewString(XmlDictionary);
- END InitStrings;
- BEGIN
- globalTimestamp := 0;
- repositories := NIL;
- InitStrings;
- NEW(registry,NIL); NEW(indexRegistry);
- END Repositories.
|