Alfresco Quick upload

In Alfresco there is no simple way to modify uploading code. You can't just copy and customize org.alfresco.web.bean.content.AddConteneDialog class and /jsp/content/add-content-dialog.jsp ie you can use add-content-dialog.jsp and modify it, but when you try to use AddContentDialog class updated in your project, it doesn't work. I found somewhere on forums (sry, i can't find a link) that add-content-dialog.jsp is just a page snippet and when you coding your own dialog, you must write code for whole page and there is problem with r:upload component. So i'll try to describe my simple solution for QuickUpload content to Alfresco through a Servlet.

In Alfresco there is no simple way to modify uploading code. You can't just copy and customize org.alfresco.web.bean.content.AddConteneDialog class and /jsp/content/add-content-dialog.jsp ie you can use add-content-dialog.jsp and modify it, but when you try to use AddContentDialog class updated in your project, it doesn't work. I found somewhere on forums (sry, i can't find a link) that add-content-dialog.jsp is just a page snippet and when you coding your own dialog, you must write code for whole page and there is problem with r:upload component. So i'll try to describe my simple solution for QuickUpload content to Alfresco through a Servlet.

My servlet – UploadAnalysisFileServlet – extends javax.servlet.http.HttpServlet, i'm using both methods – GET and POST too. (If you don't know how servlets work, just look at this tutorial) I'm using asynchronous requests and iframe, which work "behind scene" and after success user can handle some more action. Actions are following:

  1. View page with select file input and upload button in a form 
  2. After file select and upload button press is AJAX Request fired and file and information are transfered between servlet and client
  3. If file is successfully loaded, iframe views a succesfully-uploaded-image.gif and ok button is enabled
  4. QuickUpload bean control is triggered – aspects and properties are added to new content
  5. File is succesfully uploaded and properties setted up, so back to space view

Simplified "action diagram":
 
 
Now let's look inside code snipets; firstly item one, View page with select file input and upload button in a form

<iframe id="dialog:dialog-body:upload_target" src="progress_anim.gif" style="visibility:hidden"></iframe>
<div id='dialog:dialog-body:fileDiv'>
      <h:inputHidden id="alfFileId" value="#{QuickUpload.fileId}" />
      <input type="file" id='dialog:dialog-body:alfFileInput' name="alfFileInput"/>
      <input type="button" value="upload" onclick="sendAjaxRequest();" id='dialog:dialog-body:uploadButton'/>
</div>

 This is just an hidden iframe with content of animation of progress icon and a simple form with upload input type and button, which triggers following JavaScript routine. Ajax calling is based on Prototype JavaScript Framework.
 function sendAjaxRequest(){
    var form = document.getElementById('dialog');
    document.getElementById('dialog:dialog-body:fileDiv').style.visibility = "hidden";

    form.action = '/alfresco/uploadAnalysisFileServlet';
    form.enctype= 'multipart/form-data';
    form.target = 'dialog:dialog-body:upload_target';

    var ifr = document.getElementById('dialog:dialog-body:upload_target');
    ifr.style.visibility = "visible";
    var doc = null;  
    if(ifr.contentDocument)  
      doc = ifr.contentDocument;  // note: this is varying for different browsers!

    var pars = "uploadid=" + document.getElementById("dialog:dialog-body:alfFileId").value;
    var myAjax = new Ajax.Request("/alfresco/uploadAnalysisFileServlet",
         { method: 'get', parameters: pars, onComplete: checkExists });

    form.submit();
    
    form.action = '/alfresco/faces/jsp/dialog/container.jsp';
    form.enctype= 'application/x-www-form-urlencoded';
    form.target = '';
}

First action is getting a form of dialog, then default action of this form is redirected to my servlet. After that is an ID sent through get method to servlet and a file is sent too, viapost metod, thanks to form.submit(). After this sending is dialog form redirected back to original value and onComplete method is called (it just reads a responseText and check, if it is true or false), which enables OK button.
 
How are post and get methods handled in servlet? A org.alfresco.web.bean.FileUploadBean class is used:
 
 public void doGet(HttpServletRequest request,HttpServletResponse response)throws ServletException, IOException{
       this.fileUploadBean = new FileUploadBean();
       this.uploadId = request.getParameter("uploadid");
       PrintWriter out = response.getWriter();
       out.println("uploadId = "+this.uploadId);
   }
A doGet method just creates a new FileUploadBean and sets and returns ID of file (I'm using this just for debugging and experimenting purposes, it can all be placed just in a Post method). Now let's handle post method data:
 
public void doPost(HttpServletRequest request,HttpServletResponse response)throws ServletException, IOException{
       HttpSession session = request.getSession();
       ServletFileUpload upload = new ServletFileUpload(new DiskFileItemFactory());
      
       List<FileItem> fileItems = upload.parseRequest(request);
       for (FileItem item : fileItems){
           if(item.getFieldName().equalsIgnoreCase("alfFileInput")){
               String filename = item.getName();
               filename = FilenameUtils.getName(filename);
               final File tempFile = TempFileProvider.createTempFile("alfresco", ".upload");
               item.write(tempFile);
               this.fileUploadBean.setFile(tempFile);
               this.fileUploadBean.setFileName(filename);
               this.fileUploadBean.setFilePath(tempFile.getAbsolutePath());
           }
       }
      
       session.setAttribute(FileUploadBean.getKey(uploadId), this.fileUploadBean);
       response.setContentType("text/html");
       PrintWriter out = response.getWriter();
       out.println("<img src="/alfresco/images/icons/deploy_successful.gif"/>");
   }
This snippet is hardly simplified, but idea is still readable: it reads all file items and if one of them is our file input (alfFileInput), temporary file is created and fileUploadBean properties are set. Then is set an attribute in a session – whole fileUploadBean and a response is sent back to JavaScript client – view of succesfull_upload inside iframe.
 
At this phase a user can do "OK", so QuickUpload's finishImpl method is triggered. It handles a uploaded file following simple way:
FacesContext ctx = FacesContext.getCurrentInstance();
FileUploadBean fileBean = (FileUploadBean)ctx.getExternalContext().getSessionMap().
                                get(FileUploadBean.FILE_UPLOAD_BEAN_NAME.concat("-"+this.getFileId()));
       
if(fileBean != null){
    this.file = fileBean.getFile();
    this.fileName = fileBean.getFileName();
 
    NodeRef spaceRef = this.navigator.getCurrentNode().getNodeRef();
    FileInfo fileInfo = this.getFileFolderService().create(spaceRef, fileBean.getFileName(), ContentModel.TYPE_CONTENT);
    NodeRef fileNodeRef = fileInfo.getNodeRef();
               
    Map<QName, Serializable> fileDesc = new HashMap<QName, Serializable>(3, 1.0f);
    fileDesc.put(ContentModel.PROP_TITLE, this.fileName);
 
    ContentWriter writer = this.contentService.getWriter(fileNodeRef, ContentModel.PROP_CONTENT, true);
    writer.putContent(this.file);
}
Firstly a FileUploadBean is extracted back from SessionMap, then a content inside currentNode is created with specified parameters (it is also possible to add some aspects and properties there). After all that just "return outcome;" and hooray, we have simple working QuickUpload routine for Alfresco ;-).

Ahr – to the – Rem – to the – Pa

Ráno v Aachenu bylo stejně voňavé, jako noc, byla tu poblíž asi nějaká pekárna, nebo tak něco. Vlastně už si vzpomínám, přímo v nádražní budově byla kavárnička, takže jsme posnídali Laté a výborný šneky s rozinkama. Dnešní plán byl dostat se do Ahrweileru, prohlídnout Cold War bunkr a potom přespat někde na vinici. Žel bohu, osud bývá nevypočitatelná mrcha. Nebo bohudík?

Ráno v Aachenu bylo stejně voňavé, jako noc, byla tu poblíž asi nějaká pekárna, nebo tak něco. Vlastně už si vzpomínám, přímo v nádražní budově byla kavárnička, takže jsme posnídali Laté a výborný šneky s rozinkama. Dnešní plán byl dostat se do Ahrweileru, prohlídnout Cold War bunkr a potom přespat někde na vinici. Žel bohu, osud bývá nevypočitatelná mrcha. Nebo bohudík?

Plánem bylo pořídit S-Bahen lístek, což je jakási obdobanašeho Integrovaného dopravního systému. Je to celodeňák až pro 5 osob a platí jeden den, cena = E33. To jsme ovšem nevěděli. Tento lístek nám nabídla nějaká důchodkyně, že jej neprojede a nechánám jej za 30 Eur. Vypadalacelkem věrohodně, tak jsem podojil cash-machine u nádraží, babča dostala 30 éček a my s klidným svědomím nastoupili do vlaku. Zajímalo by mě, jestli nás přechcala záměrně, nebo to nevěděla – došel průvodčí a nastal virvál, v němčině, protože anglicky neuměl. Nakonec jsme to uhráli na to, že si zapíšeme na interrail pas další den a on nám dá pokoj. Zbytek cesty až do Kolína nad rýnem jsme nadávali, jak se nám povedlo zašantročit 30Eur a jeden den na projetí.

V Kolíně neměli ani sprchu, takže jsme nacpali batohy do plně automatické úschovny – pěkná věc, je to malá skříňka uprostřed haly a bagáž odjede někam do podzemí :-). Následovalo stručné vyfocení přednádražního prostoru a výlet vlakmo směr Bonn – Remagen – Ahrweiler.

img_0345

Ahrweiler je moc pěkný městečko obklopený vinicema, kde už hrozny dozrávaly :-p a všude byla cítit natěšenost na vinobraní. V tomhle lázeňským městě to ovšem bylo přeplněný "turistama nad 65 roků", takže jsme se vydali vzhůru do kopců přímo do studenoválečného bunkru.

Street in Ahrweiler

Za mnoha a mnoha těžkými panceřovými dveřmi se skrývá komplex, který měl uchránit vládu (tenkrát sídlící v Bonnu) po třicet dni od hermetického uzavření tohoto prostoru. Potom, vážený pane kancléři, následuje ne příliš pěkná smrt ;-). Zkusím spáchat vlastní blogpost s touto tématikou (nenepěkné umírání, ale tento bunkr). Teď zatím fotka velína ve stylu Death Star.

img_0310

img_0267

No ale tradá zase rychle ven do tepla, přímo k výhledům od vchodu do bunkru. Pánové by měli určitě radost, kdyby z bunkru byl "sklépek" a oni se mohli upít, jenže tohle štěstí by bývali neměli.

img_0236

Teď teda zpět do Remagenu podívat se na legendární most. Ovšem k vidění tu toho moc není, především díky faktu, že most jaksi spadl :-). Tak aspoň tankery plující po Rýně, příjemná koupel nohou a obejití torza mostu s muzeem v tomto torzu se nacházejícím. Příjemné, škoda, že odtud musíme pryč, zase směrem Bonn – Koln.

img_0328

img_0339

Kolínem to ovšem dneska nekončí, ještě musíme chytnout spoj na Paříž skrze Bruxelles. Takže nás čeká první TGV a poté noční Thalys. Hnusný vlaky to jsou, nevím, co na nich kdo vidí. Díky tomuto pitomýmu Thalys jsem dostal vlka, takový nepohodlný a nepříjemný sezení jsem snad ještě nezažil. Hlavně že za tenhle expres chtěli příplatek, holt skoro jako České dráhy :-(. Ale o Paříži až někdy příště, dneska už na to nemám žaludek!

Ohleduplnost českých řidičů…

…nezná mezí – jsou milí, usmívají se na sebe, občas stáhnou okýnko, aby mohli slušně pozdravit, nebo se jen zeptat, jak se dneska máte. Nikam nespíchají, za jízdy si zpívají, na přechodu chodce pustí a na křižovatkách nikdy neblokují šalinu při odbočování. Ještě jsem neviděl řidiče, který by předjel autobus a dupl na brzdu, stejně tak nepředjíždí přes plnou čáru, myšku znají pouze jako neškodné malé zvířátko. Vědí, že zip není pouze součástka na oblečení, když je hlavní ucpaná, jsou schopní pustit někoho z vedlejší ulice. Ještě je mnoho hezkých věcí, které se mně na nich líbí, opravdu! Hoši, děkuju!
…nezná mezí – jsou milí, usmívají se na sebe, občas stáhnou okýnko, aby mohli slušně pozdravit, nebo se jen zeptat, jak se dneska máte. Nikam nespíchají, za jízdy si zpívají, na přechodu chodce pustí a na křižovatkách nikdy neblokují šalinu při odbočování. Ještě jsem neviděl řidiče, který by předjel autobus a dupl na brzdu, stejně tak nepředjíždí přes plnou čáru, myšku znají pouze jako neškodné malé zvířátko. Vědí, že zip není pouze součástka na oblečení, když je hlavní ucpaná, jsou schopní pustit někoho z vedlejší ulice. Ještě je mnoho hezkých věcí, které se mně na nich líbí, opravdu! Hoši, děkuju!

Konečně přes kanál

Oukej, konečně došlo na Den D, sbalili jsme saky-paky a vyrazili na blinda směr Londýn. Nebo spíš ani ne tak na blinda, tušil jsem tam existenci nějaké cestovky, která bude schopná dodat interrail jízdenku na počkání a bohudík tomu tak skutečně bylo, takže jsem si případněj průser, kdybychom lístek nesehnali uvědomil, až když bylo nebezpečí zažehnáno.

Oukej, konečně došlo na Den D, sbalili jsme saky-paky a vyrazili na blinda směr Londýn. Nebo spíš ani ne tak na blinda, tušil jsem tam existenci nějaké cestovky, která bude schopná dodat interrail jízdenku na počkání a bohudík tomu tak skutečně bylo, takže jsem si případněj průser, kdybychom lístek nesehnali uvědomil, až když bylo nebezpečí zažehnáno.

Takže zpátky k plánu – flákat se po Londýně a někdy před půlnocí nastoupit do vlaku směr Dover a tam někde přečkat noc. Co o Londýně? Těžko říct, připadlo mi, že po tom roce, co jsem tu nebyl je všechno pořád stejný. Ani nevím, proč mám takovou slabost pro tohle město, nebo spíš pro jeho jeden park 😉 . Každopádně letos jsme jenom proběhli cípkem poblíž speeking corner a to ne při této návštěvě, ale až cestou zpět. Při této příležitosti jsme pouze mrkli na dno řeky při odlivu (pěknej bordel tam je, jen co je pravda!) a počkali si u Tower Bridge na večer.

Roots of society

Cesta směr Dover byla více než pohodová, i když jsme jeli načerno – zřejmě, protože platnost interrail byla až od půlnoci, jenže dle pravidel je možné využít vlak přes půlnoc po sedmé hodině večerní, takže tahle skutečnost je docela sporná, asi by nevěděl ani štiplístek, kdyby se zastavil – chodil pouze kolem a kolem celou cestu a nic nekontroloval. Každopádně do Doveru jsme dorazili tuším něco po půlnoci, plán byl stručný: najít přístav a přespat v něm na sedačkách. Dostat se k přístavu se nám nakonec po nějaké době podařilo, spát se dá v příjezdové hale, poměrně pohodlné sedačky – měkkoučký polstrování, navíc jsme tu nebyli sami. Většinu noci byl klid, jen nad ránem začaly přijíždět trajekty a kolem chodilo docela dost lidí, ale spánek to moc nerušilo – v jednu chvíli jsem se probudil a nade mnou stál chlap a telefonoval – spal jsem totiž přímo pod veřejnou linkou na půjčovnu aut, tak jsem jen rozloupl oko a mrknul nahoru a za chvíli spal dál :-). Po úplným vzbuzení ráno, tuším něco po sedmé hodině, následovala stručná hygiena – xicht a zuby v přidružených hajzlících a výlet pro lístek na trajekt a po zjištění, že jede až za cca 2 hodiny procházka do místního Mourissona pro koblížky a flašku mlíka.

Morning in Dover

Potom už následovalo nalodění se a nezáživná plavba směr Žabožroutov. Cestou nás doprovázely davy racků a reklamní hlášení; nákup levného alkoholu jsme zneužili až při zpáteční cestě ;-). V Calais v budově přístavu jsou sprchy zdarma, výborný překvápko, krásně čistý, teplá voda, sprchový gel (aka tekuté mýdlo na ruce ;-)) a potom už jen schnutí a oběd před terminálem.

Calais ferry port

V Calais se nám nějak nepodařilo vychytat spoje autobusu na nádraží, tak jsme vyrazili pěšmo směr city center. Gare de Ville se nám podařilo najít poměrně rychle, na spoj jsme měli štěstí, vlak odjížděl za 5 minut, takže vzhůru směr Lille. Obloha bez mráčku, vedro vskutku tropický, vlak prázdnej, sice z roku raz-dva, ale aspoň se stahovacíma okýnkama. V Lille na "Flanďákově nádraží" byl docela shon. Díky strýčkovi googlovi mám aspoň pohled na nádražní budovu a přílehlé okolí (naše návštěva se rovnala rychlýmu exitu z nádraží, pochodu do Carrefouru pro lahev pití a návrat zpět), protože v Lille už frčí Street View. Bohužel, v hale jsme si ještě poseděli nějakou dobu a naučili se první slovíčko – fermeture. Frantíci totiž mají vůči angličtině averzi, takže žádné mezinárodní psané informace či hlášení nádražního rozhlasu se nevedou. Bohudík aspoň na informacích chlapík mluvil anglicky, takže jsme dohodli náhradní spojení směr Bruxelles s jedním přestupem v [muchro:], musel mi chudák spelovat název tohoto města několikrát, ale stejně jsem tomu jeho chrochtání nerozuměl, takže tiskárna to jistila ;-).

V Brusselu jsme se dověděli, že se asi do Kolína nedostaneme, takže jsme vykoumali alternativní způsob dopravy – nějakým expresem z jihu možná až do Berlína. Něco přes hodinku čekání jsme vyplnili procházkou kolem nádraží a sehnání večeře v jakýmsi bistru, kde chlapík neuměl slovo anglicky, ale dostali jsme mega porci hranolek, sendvič, pití a já nevím co ještě za tuším 7éček dohromady, což je opravdu zadarmo! Hned vedle ještě bagetky za babku a nějakej pakistánec s levnýma čajama a vodou. Radost ovšem zkazila cesta zpět na nádraží – nějakej arabskej shop o velikosti 2×2 metry se čtyřma kamerama a 2 hlídačema (když pominu 2 prodavače za mini pultíkem), kde jsme nechali docela slušnou pálku za sýr a 2 "nejsilnější belgické ležáky".

V expresu, nebo spíš odporným doupěti jsme byli nacpáni do hitláku, kde jela rozjařená Hitler-jungend odněkud z paříže – všude lahve, konopa, bordel… ale byli docela společenští, tak jsme se dověděli, že tu jedou nějací dva šéfkové, kteří jsou specialisti na kontrolování interrail pasů a asi nás vyhodí z vlaku. Takže jsme si ustlali na chodbičce mezi sušícíma se pohorama s ponožkama a opřeni o batoh a stojan na kola usnuli hnusným spánkem (po vysrkání onoho belgickýho humusu – bohužel už nevzpomenu, jak se ten odpornej patok jmenoval). Po cca 2 hodinách vlak zastavil na červenou (nebo spíš se asi rozpojoval) v Aachenu, takže jsme vyrazili dveře a vypadli směr noc. Kolem nádraží hrůza a děs – opilci, boveři, loveři a podobná havěť, naštěstí jsme poblíž našli flek na spaní – parkoviště (na druhej pokus, na prvním ideálním spacím fleku spal bover a když jsme se přiblížili, začal si docela nepěkně povídat sám se sebou, což s jeho děsivým vzhledem stačilo k tomu, abychom se fofrem dekovali pryč). Já měl alumatku, brácha bivakoval na vrstvě plakátů, kterou jsme urvali poblíž. Na betonu to bylo ne zrovna dvakrát příjemné, ale únava byla silnější, takže druhá homeless noc proběhla taktéž bez problémů (až na nehoráznou zimu, brr!!).