Iratmintakezelés Word-ben Java Swing-es alkalmazáson keresztül #2

Miután ki lett dobva a JAXB-s megoldás a Word felé fordultam, hogy feltérképezzem milyen lehetőségeim vannak.

2. zsákutca: VBA

Plan#1 Az volt a terv, hogy amikor Java-ból előállítom a dokumentumot, akkor a CustomDocumentProperty-be helyezem el a szükséges kódtáblák értékeit és az egyéb értékeket amelyek kellhetnek az iratminta kitöltése során. Az iratminta tervezéskor megadott “markup”-ok alapján létrehozom a komponenseket, feltöltöm a kódtáblákat és az összes vezérlő ami létre lett így hozva ha változik a tartalma beírja az értéket a CustomDocumentProperty-be, hogy mentés után vissza tudjam onnan olvasni az XML állományból.

Ennek érdekében azt kellett kideríteni, hogy mi az amit a Word tud és hogyan lehet benne ezt/azt csinálni:

  • komponensek dinamikus létrehozása egy adott pozícióba,
  • szövegek keresése,
  • szövegek elrejtése,
  • XML parsolás,
  • Custom Document Property-k kezelése,
  • dinamikusan létrehozott komponensekhez esemény hozzáfűzése

Ott akadtam el, hogy a dinamikusan létrehozott komponensekhez, hogyan fogom tudni az eseménykezelést hozzá adni, mivel a VBA-n az eseménykezelők paramétereinél nem szerepel a Sender, azaz nem tudnám eldönteni, hogy melyik komponens változott. Lehetett volna olyan “megoldást” is készíteni, hogy minden egyes változás során az összes komponens lementi az állapotát, de ez nem tetszett volna.

Így a VBA-s megoldás is a kukába került!

 

VSTO

Következő versenyző egy VSTO-s megoldás lehet, azonban egy korábbi a néhai Architektúra Fórum-on elkövetett vizsgálódás során az volt a tapasztalat, hogy az ilyen megoldásokat telepíteni szükséges. A telepítés jelen esetben szóba sem jöhet, hiszen az iratmintákat a megrendelő a Word-ben akarja megtervezni és egy java-s alkalmazásból kell manipulálni az iratminták tartalmát. Ezek alapján nagyon szkeptikusan álltam neki megismerni egy újabb ismeretlen világot.

Jöhetett a Visual Studio 2008 Professional beszerzése, telepítések, servicepackok, nem mondhatnám, hogy gyorsan túl estem rajta.

Gyorsan készítettem egy egyszerű Word-os dokumentum alapú VSTO-s alkalmazást. A build során előállt egy doc és egy dll, mivel ez alkotja a solutiont. A döntő pillanat csak most következett, ha elmentem xml formátumban a dokumentumot, akkor képes-e még működni a VSTO-s solution? És igen működött! Így nagy kő esett le a szívemről, mivel ha ez sem működött volna akkor tényleg nem tudom, hogy mihez lehetett volna hozzányúlni.

Plan#2 Most, hogy már menedzselt környezetbe tudok dolgozni az eredeti elképzelés is megváltozott. A kódtáblák tartalmát már nem teszem bele a dokumentumban, hanem WebService-ként kérem majd el a java klienstől. Úgy tervezem, hogy az adatokat továbbra is CustomDocumentProperty-ként mentem vissza.

A megrendelő egyik legnagyobb problémája jelenleg (még nem látott semmit az egészből; igaz még nincs is mit), hogy a többsoros, formázott jogszabály-hivatkozást egyelőre nem tudom a ComboBox-ban as-is megjeleníteni. Majd a végén ha minden működik ezzel is fogok foglalkozni egy picit.

A VBA-s napok tapasztalatait (szöveg keresés előre, hátra; XML kezelés; dinamikus komponens létrehozás; stb.) átültettem VSTO környezetbe. Viszonylag ez a rész gyorsan ment, mivel már nem kellett kitalálni, hogy mit hogyan kell, csak az egyik ismeretlen nyelvből és környezetből kellett egy másik ismeretlen nyelvbe és környezetbe átírni a korábbiakat.

Eljött az a pillanat, hogy a klienst meg kellene szólítani, hogy szolgálja ki a WebService-ket annak érdekében, hogy a ComboBox-okat fel lehessen tölteni tartalommal. Ez így szépen hangzik, de én a mai napig nem vagyok kibékülve a java WS fejlesztői támogatásával (vagy csak nem értek hozzá). Ráadásul a WS kiszolgálást a klienstől várnám el. Ezt az ötletemet elég hamar elvettetem, de és próbáltam más megoldásokat keresni.
További gondolatok a probléma megoldására:

  • a kliens tartalmaz egy HSQLDB nevű beágyazott SQL szervert ezt meg kellene próbálni elérni valahogy

Körülnéztem, de hirtelen nem találtam megoldást. Megtaláltam a HSQLDB .Net-esített portolását de a megosztott adatbázis állomány kezelés miatt elvetettem ezt az ötletet is. Továbbá ez esetlegesen szükséges további kommunikációt akkor is meg kellett volna oldani.

  • írjuk ki a kódtáblák tartalmát fájlba és majd felolvassuk

Ez lett volna a legegyszerűbb megoldás, viszont a “legrondább” is. A további kommunikáció problémája továbbra is fennáll, bár ezt is meg lehetett volna tenni fájlok írásával, olvasásával.

Eszembe jutott, hogy egy korábbi szintén R&D kategóriás java és silverlight fejlesztésnél (Nagy Imre és a Silverlight) JSON-ként kerültek az adatok átadásra és ebben az esetben is elég egy egyszerű HTML GET-es kérés. Akkor most már csak egy webszervert kell a kliensbe belegyúrni.

Nemrég vette át az Eclipse.org a Jetty nevű beágyazható webszervert, amiről csupa jó dolgokat írtak mindenfelé. Megnéztem, hogy mennyire könnyen lehet integrálni. Szerencsémre nagyon egyszerűen. Sőt még Servlet konténerként is könnyen be lehetett konfigurálni. így a kliens alkalmazásban futó Servlet konténer ki tudta szolgálni JSON formátumban a Word-öt, hogy a ComboBox-ok tartalmát fel tudja tölteni.

Ezzel megoldódott a kódtáblák feltöltésének a problémája, de mi legyen a többi adattal?

Plan#3 A korábbi terv az volt, hogy az előre kitölthető (szerv, ügyszám, ügyintéző, ügyfél, stb.) adatokat java-ban megírt XML manipulációval oldom meg. Azonban, hogy már volt kapcsolatom a klienssel, egyszerűbbnek látszódott arra felé terelni a probléma megoldását, hogy ezeket az adatokat is inkább kommunikációval szerezem meg a klienstől és Word szintű manipulációval kerüljenek megjelenésre. Ezzel a megoldással egyre kevesebb feladatot kell majd megoldanom java-ban, sőt talán az is elképzelhető, hogy semmit ne kelljen java szinten a dokumentumokkal varázsolni (kérdéses még, hogy a VSTO integráció, a program frissítés hogyan oldható meg).

Annak érdekében, hogy az iratban szereplő adatokat ki tudjam tölteni fel kell építenem egy Domain Model-t és az átadni. Mivel ez a rendszer 5 évvel ezelőtt készült és a szervezők még akkor sem voltak a helyzet magaslatán most kell összeraknom ezt a DomainModel-t.

Mivel az iratminta tervezésekor a tervezőnek valahogy hivatkoznia kell a Domain Model elemeire, továbbá majd ezekre az elemekre az alkalmazásnak keresnie is tudnia kell a pontozásos hivatkozást választottam. OK, OK, szépen hangzik, de hogy fogom tudni lekérdezni az így leírt elem konkrét értékét? Felmerült, hogy akkor mégsem osztály hierarchiát kellene készíteni, hanem csak egyszerű property/value párost. De ez a megoldást nem tetszett, úgyhogy inkább írtam egy kis eljárást ami a pontozott szöveg alapján kikeresi az osztály hierarchia alapján a keresett elem tényleges értékét.

using System;
using System.Collections.Generic;
using System.Text;

namespace Reflection
{
    class Program
    {
        static void Main(string[] args)
        {
            Container container = new Container();

            string result = getValue("Ugy.UgyFel.Sajatneve.teljes", container);
            System.Console.WriteLine("result=["+result+"]");

            result = getValue("Ugy.Ugyfel.SajatNeve", container);
            System.Console.WriteLine("result=[" + result + "]");
            System.Console.ReadKey();
        }

        public static string getValue(string item, object container)
        {
            string[] itemsPath = item.Split(".".ToCharArray());
            object findObject = container;
            foreach (string classPathItem in itemsPath)
            {
                System.Console.WriteLine("classPathItem=[" + classPathItem + "] object=[" + findObject.ToString() + "]");
                foreach (System.Reflection.FieldInfo fieldInfo in findObject.GetType().GetFields())
                {
                    if (fieldInfo.Name.Equals(classPathItem, StringComparison.OrdinalIgnoreCase))
                    {
                        findObject = fieldInfo.GetValue(findObject);
                        break;
                    }
                }
            }
            return findObject.ToString();
        }
    }

    class Container
    {
        public Ugy Ugy = new Ugy();
    }
    class Ugy
    {
        public Ugyfel Ugyfel = new Ugyfel();
    }
    class Ugyfel
    {
        public Nev SajatNeve = new Nev("Kiss", "Pista");
        public Nev AnyjaNeve = new Nev("Nagy", "Jóska");
        public Nev SzuletesiNev = new Nev("Boldog", "Asszony");
    }
    class Nev
    {
        public string Csaladi;
        public string Uto;
        public string Teljes;

        public Nev() {
        }

        public Nev(string csaladi, string uto) {
            this.Csaladi = csaladi;
            this.Uto = uto;
            this.Teljes = csaladi + " "+uto;
        }

        public override string ToString()
        {
            return "Neve: "+Csaladi + " " + Uto;
        }
    }
}

Futás eredménye:

classPathItem=[Ugy] object=[Reflection.Container]
classPathItem=[UgyFel] object=[Reflection.Ugy]
classPathItem=[Sajatneve] object=[Reflection.Ugyfel]
classPathItem=[teljes] object=[Neve: Kiss Pista]
result=[Kiss Pista]
classPathItem=[Ugy] object=[Reflection.Container]
classPathItem=[Ugyfel] object=[Reflection.Ugy]
classPathItem=[SajatNeve] object=[Reflection.Ugyfel]
result=[Neve: Kiss Pista]

 

Most ott tartok, hogy összerakjam a Domain Model-t, feltöltsem és átadjam a Word-nek és ott a megfelelő helyeken az értékek jelenjenek meg.

Ha továbbjutottam ismét jelentkezem!

Reklámok
Kategória: #JavaWord2003 | Közvetlen link a könyvjelzőhöz.

Vélemény, hozzászólás?

Adatok megadása vagy bejelentkezés valamelyik ikonnal:

WordPress.com Logo

Hozzászólhat a WordPress.com felhasználói fiók használatával. Kilépés / Módosítás )

Twitter kép

Hozzászólhat a Twitter felhasználói fiók használatával. Kilépés / Módosítás )

Facebook kép

Hozzászólhat a Facebook felhasználói fiók használatával. Kilépés / Módosítás )

Google+ kép

Hozzászólhat a Google+ felhasználói fiók használatával. Kilépés / Módosítás )

Kapcsolódás: %s