Eurotrip 2009 I

zacatek byl bezva. bal jsem se nechutnyho paraku, jakej pocasi predvadelo celej tyden. kdyz jsem odjizdel, bylo pod mrakem, v bratislave uz bylo pod vice mraky a vitr ukazoval, jak dokaze obalit hotdoga za 40 centu piskem. napadlo me, ze asi bude docela vesele v tomhle pocasi odlitat. a taky ze jo :-).
 
zacatek byl bezva. bal jsem se nechutnyho paraku, jakej pocasi predvadelo celej tyden. kdyz jsem odjizdel, bylo pod mrakem, v bratislave uz bylo pod vice mraky a vitr ukazoval, jak dokaze obalit hotdoga za 40 centu piskem. napadlo me, ze asi bude docela vesele v tomhle pocasi odlitat. a taky ze jo :-).
 

jen jsem dosel na letisko, zacalo bozi dopusteni: venku cerno a snury vody bicovaly drahu o sto sest. dokonce I do budovy zatikalo. to jsem zrovna daval odpocinout noham po snaze vystat si prvni misto ve fronte na brane. prej si mame s odletem pockat, blizsi info za 30 minut. behem tech 30 minut odklonili jeden let do vidne, druhy do budapesti, prijemne. ale nas pilot byl machr, vynoril se z hlmy a umne prastil strojem o pristavaci drahu a prej, ze by chtel hned letet. no proc ne! tentokrat uz jsem (poucen panem peltonem) se sproste probil az dopredu v touze chytnout sezeni u okna I bez priority boarding priplatku. prozirave, nejen kvuli sezeni: uz jsem zminoval dest, ale jeste jsem nezminoval beh v tomto desti :-). nuze, jakmile letuchtivy dav opustil kryte schodiste, zacal uprk – statecne jsem se drzel mezi prvnimi a mezi prvnimi taky dobehl do letadla – prede mnou jen par lidi, takze jsem se vmestnal aspon trochu pod strisku, mokrej od poloviny hlavy k polovine paty. ostatni museli byt uplne durch! a jako bonus jsem vychytal sicnu u cistyho okynka a kino mohlo zacit.
 
nevim, jak ma rastislav stefanik staveny ranveje, ale rolovali jsme az uuuplne dozadu a podle puncoch na nas vitr sel z asi 10 hodin. v posadce byl nejakej ind nebo co to bylo a byl ze vseho nehorazne vysmatej. jakmile jsme se odlepili od drahy, svihlo to s nama plavmo vpravo, zajimave :-). ale zajimavejsi prislo hned zahy: sotva par metru nad zemi jsme se propadli uplne nehoraznym zpusobem, zezadu byl slyset krik :-D. jeste to trochu houpalo, ale jakmile jsme proletli tou vatou, byl klid.
frankfurt uz tak dramaticky nebyl, mraku bylo pomalu a misty bylo videt na zem, pekny pohled, k okynku se budu probijet casteji! snad by stala za zminku jen neukaznenost nemcu (nebo neznalost anglictiny), protoze chvili pote, co kapitan zarval a pripoutala se I posadka, ulickou spacirovala nejaka nemka smerem vpred a zahy I zpet, umravnena indem (nevim, co chtela, zachod je vzadu a pistoli nemela).
po pristani sklidil kapitan potlesk a ja vyrazil hledat terminal a42, bezvysledne. jak se totiz zahy ukazalo, byl jsem na uplne jinem letisti, nez jsem cekal :-). ok, co se da delat, ale jedinej shuttle do mesta stal 12E, cesta trva cca 2 hodiny, navic mame spozdeni…no nepekne!
nastesti jsme vyrazili o neco driv a ja mel hodinku na probehnuti okoli frankfurtskyho nadrazi a porizeni aspon priblizne te fotky, kterou jsem si vyhlidl z autobusu.
 
pak uz jen koupe lahve vody, pizzy a sup do spozdeneho ice a v nem rychlosti 250kph trada na hamburg, kde ted sedim v pekarne, srkam dalsi kafco, chaluju kolac s vybornou marmeladou a cekam na vlacek do neumunsteru, kde snad premluvim stiplistka, aby me pribalil do jejich expresu smer odense, protoze tu neni mozny zaplatit rezervacku pomoci automatu, ani na informacich, divne :-(.
 

Delete dialog workaround

Write this one, or not to write this blogpost? That is the question :-). But I would like to simply remember for some things i did, so let's do it! In my DMS I have some multimedia content saved and this content has attached description in xml file. Also I have my own space view (more info here), so I show just that multimedia content. In case of deletion that content I want to delete that xml too, so how to do that?

Write this one, or not to write this blogpost? That is the question :-). But I would like to simply remember for some things i did, so let's do it! In my DMS I have some multimedia content saved and this content has attached description in xml file. Also I have my own space view (more info here), so I show just that multimedia content. In case of deletion that content I want to delete that xml too, so how to do that?

First we need to create an action (it's just a copy of original action ;-)) specification in web-client-config and name it – in my case "delete_doc_shm":

<action id="delete_doc_shm">
    <permissions>
        <permission allow="true">Delete</permission>
    </permissions>
    <evaluator>org.alfresco.web.action.evaluator.DeleteDocEvaluator</evaluator>
    <label-id>delete</label-id>
    <image>/images/icons/delete.gif</image>
    <action-listener>#{BrowseSessionBean.deleteFile}</action-listener>
    <params>
        <param name="id">#{actionContext.id}</param>
        <param name="ref">#{actionContext.nodeRef}</param>
    </params>
</action>

It's pretty simple, just a definition of action with Evaluator and wanted permissions. I wrote a blogpost about this a year about :-). Now I have an action, so I need to add it into some group, or view link directly. Action groups are defined in web-client-config too:

<action-group id="session_browse">
    <show-link>false</show-link>
    <style-class>inlineAction</style-class>
    .  .  .
     <action idref="delete_doc_shm" />
</action-group>

And view of this group is realised by actions component (r variable is variable defined by richListComponent, library prefix r is Alfresco's repo taglib):

.  .  .
<r:actions id="actions_menu_1" value="session_browse" context="#{r}" showLink="false" styleClass="inlineAction" />
.  .  .  

The result's like this (there's no difference in original view of that actions menu and this, but functionality – see below ;-)):

Image and video hosting by TinyPic

Now some application logic: In case of pressing our delete butto, BrowseSessionBean.deleteFile() method is called. This method just do same things that original BrowseBean.deleteFile() does, but redirects to my own dialog:

public void deleteFile(ActionEvent event) {
    .  .  .  some foo – bar stuff  .  .  .
    FacesContext fc = FacesContext.getCurrentInstance();
    NavigationHandler navigationHandler = fc.getApplication().getNavigationHandler();
    navigationHandler.handleNavigation(fc, null, "dialog:deleteVcfFile");
}

This dialog is defined in web-client-config like

<dialog
    name="deleteVcfFile"
    page="/jsp/dialog/delete.jsp"
    managed-bean="DeleteVcfContentDialog"
    icon="/images/icons/delete_large.gif"
    title-id="delete_file"
    description-id="delete_file_info" />

and points to DeleteVcfContentDialog bean:

<managed-bean>
    <description>The bean that backs up the Delete Content Dialog</description>
    <managed-bean-name>DeleteVcfContentDialog</managed-bean-name>
    <managed-bean-class>cz.shmoula.dialog.DeleteVcfContentDialog</managed-bean-class>
    <managed-bean-scope>session</managed-bean-scope>
    <managed-property>
        <property-name>navigator</property-name>
        <value>#{NavigationBean}</value>
    </managed-property>
    .  .  .  more properties  .  .  .
</managed-bean>

Class managing this bean extends DeleteContentDialog and has only one method – finishImpl. See following source, it's commented:

public class DeleteVcfContentDialog extends org.alfresco.web.bean.content.DeleteContentDialog {

    @Override
    protected String finishImpl(FacesContext context, String outcome)throws Exception {
        // get the content to delete
        VcfNode node = new VcfNode(this.browseBean.getDocument());
        if (node != null) {
            if (ContentModel.TYPE_MULTILINGUAL_CONTAINER.equals(node.getType())) {
                // delete the mlContainer and its translations
                getMultilingualContentService().deleteTranslationContainer(node.getNodeRef());
            } else {
                // getting attached xml node
                Node descriptionXml = node.getXmlNode();
                // and if xml exists, delete it!
                if(descriptionXml != null)
                    this.getNodeService().deleteNode(descriptionXml.getNodeRef());
                
                // delete the node
                this.getNodeService().deleteNode(node.getNodeRef());
            }
        }
        return outcome;
    }
}

As I can see, it'll be much better to implement some transactions inside this method to 'do some atomicity' 8-). VcfNode is my Node extension, I'll try to describe it in next blogpost.

So, it's pretty easy to workaround system dialogs thanks to Alfresco source code. But sometimes you can find things, which looks like there is no source in sdk 🙁 but google always helps!

Vývoj pod Linuxem na PS3

Na serveru IBM developer Works vyšla série článků, která se zabývá vývojem pod Linuxem na Playstation 3. V prvním díle je popsáno, jakým způsobem vůbec Linux na tomto stroji běží, či jaká jsou omezení a dále se věnuje instalaci Fedory, ve druhém díle je potom prostor věnován optimalizacím systému za účelem získání více volné paměti. A konečně ve třetím díle se autor věnuje optimalizacím grafického prostředí, aby bylo použitelné.
Na serveru IBM developer Works vyšla série článků, která se zabývá vývojem pod Linuxem na Playstation 3. V prvním díle je popsáno, jakým způsobem vůbec Linux na tomto stroji běží, či jaká jsou omezení a dále se věnuje instalaci Fedory, ve druhém díle je potom prostor věnován optimalizacím systému za účelem získání více volné paměti. A konečně ve třetím díle se autor věnuje optimalizacím grafického prostředí, aby bylo použitelné.

Spíše než nějaká vývojová příručka mi tato série ovšem připadá více jako informace o způsobu, jak Linux na PS3 běží a jak provádět základní optimalizace, aby byl vůbec použitelný na tomto stroji. Co mě ovšem vůbec nepotěšilo je, že po přečtení se mi definitivně rozplynul sen zprovoznit na PS3 World of Warcraft, takže koupi této mašinky oppět o něco oddálím, pokud do ní vůbec půjdu. Škoda :-(.

Android 1.5 problem in Eclipse

I just updated my Android SDK to version 1.5. It was so easy, but there is a problem with generating new R.java in Eclipse under Linux. Guess why: android sdk is distributed in .zip packages, so there are no file mode bits setted. So under tools/ directory you need to chmod +x android-sdk/tools/* and also under each platform – chmod +x android-sdk/platforms/android-*/tools/* . Now it should works correctly. If not, simply remove gen directory from your project and do Clear project…

I just updated my Android SDK to version 1.5. It was so easy, but there is a problem with generating new R.java in Eclipse under Linux. Guess why: android sdk is distributed in .zip packages, so there are no file mode bits setted. So under tools/ directory you need to chmod +x android-sdk/tools/* and also under each platform – chmod +x android-sdk/platforms/android-*/tools/* . Now it should works correctly. If not, simply remove gen directory from your project and do Clear project…

Inteligence Windowsáků…

…je asi opravdu záporná, pokud nějaká existuje. Donedávna jsem si myslel, že se to týká pouze BFUček, ale teď mě zas tak vytočil kolega ajťák (dokonce vývojář), že se musím někde vypsat. Snažil se na sdíleném wokenním testovacím počítači rozchodit nějakou aplikaci a ptal se jestli tam mám nastavenej firewall. Říkám že jo, ať si aplikaci přidá do trusted, nebo ať na chvíli sníží úroveň ochrany a on odpověděl, že ho killnul, že jestli tam mám ještě něco. Říkám že ne a začínám mu nadávat a on jen opáčí tím, že jsme stejně za NATem. Pomyslel jsem si něco o prdeli a faktu, že včera kvuli nákaze přeinstalovával svůj počítač a pouštím to z hlavy. A to jsem považoval za úsměvnou příhodu, kdy mě známá před časem říkala, že ji syn naučil, "když jí nejede skype a icq vypnout tyhle dvě ikonky tady vpravo dole" (firewall a antivir). Takže bych Vás rád poprosil, ať si klidně posíláte mejly s fotkama štěňátek na rozdávání, finanční příspěvky MS za každý přeposlaný mejl, Powerpoint prezentace se zvířátkama a moudrýma frázema i ty Wordovské dokumenty s jedním řádkem textu, ale nehrabte se v nastavení ochrany počítače, a když už, tak to pak zase vraťte zpět. Jinak vám ty Windowsy, viry a prasečí chřipky z celýho srdce přeju!
…je asi opravdu záporná, pokud nějaká existuje. Donedávna jsem si myslel, že se to týká pouze BFUček, ale teď mě zas tak vytočil kolega ajťák (dokonce vývojář), že se musím někde vypsat. Snažil se na sdíleném wokenním testovacím počítači rozchodit nějakou aplikaci a ptal se jestli tam mám nastavenej firewall. Říkám že jo, ať si aplikaci přidá do trusted, nebo ať na chvíli sníží úroveň ochrany a on odpověděl, že ho killnul, že jestli tam mám ještě něco. Říkám že ne a začínám mu nadávat a on jen opáčí tím, že jsme stejně za NATem. Pomyslel jsem si něco o prdeli a faktu, že včera kvuli nákaze přeinstalovával svůj počítač a pouštím to z hlavy. A to jsem považoval za úsměvnou příhodu, kdy mě známá před časem říkala, že ji syn naučil, „když jí nejede skype a icq vypnout tyhle dvě ikonky tady vpravo dole“ (firewall a antivir). Takže bych Vás rád poprosil, ať si klidně posíláte mejly s fotkama štěňátek na rozdávání, finanční příspěvky MS za každý přeposlaný mejl, Powerpoint prezentace se zvířátkama a moudrýma frázema i ty Wordovské dokumenty s jedním řádkem textu, ale nehrabte se v nastavení ochrany počítače, a když už, tak to pak zase vraťte zpět. Jinak vám ty Windowsy, viry a prasečí chřipky z celýho srdce přeju!

Customizing Simple Search

Some time ago I made customized advanced search results view – no two boxes like in standard Alfresco, but three boxes – the third one for viewing special content type. Now I wanted to add this results screen as a default result of searching via the simple search box.

Some time ago I made customized advanced search results view – no two boxes like in standard Alfresco, but three boxes – the third one for viewing special content type. Now I wanted to add this results screen as a default result of searching via the simple search box.

When I firstly saw r:simpleSearch component and no documentation, I wasn't happy. But after while I realized that it's very simple, thanks to actionListener parameter on that component:

 <r:simpleSearch id="search" actionListener="#{BrowseSessionBean.search}" />

This component creates that very known search box

Image Hosted by ImageShack.us

That action listener, search, is defined in BrowseBean, but I did my own (I copied and edited it :-)). All what this listener does is just setting Search Context and then redirects to results page – returns adequate outcome string to faces navigator.

 public void search(ActionEvent event){
        UISimpleSearch search = (UISimpleSearch)event.getComponent();
        this.navigator.setSearchContext(search.getSearchContext());
        
        FacesContext context = FacesContext.getCurrentInstance();
        context.getApplication().getNavigationHandler().handleNavigation(context, null, "browseSearchResults");
    }

 Navigation rule in faces config navigates in this case from everywhere to my own search results page thanks to this rule:

<navigation-rule>
        <from-view-id>/jsp/*</from-view-id>
        <navigation-case>
            <from-outcome>browseSearchResults</from-outcome>
            <to-view-id>/jsp/archivace/view-search-results.jsp</to-view-id>
        </navigation-case>
</navigation-rule>

That's all, view-search-results is up to you 🙂

Playing with titlebar and navigator II

In last blogpost I wrote about titlebar and menu in it. Also I promised some navigator hacking, which is more complex (and crazy has many javascript code) and amazing, so I decided to write whole blogpost on it. Here we are go!

In last blogpost I wrote about titlebar and menu in it. Also I promised some navigator hacking, which is more complex (and crazy has many javascript code) and amazing, so I decided to write whole blogpost on it. Here we are go!

Navigator jsp is pretty simple, but it's not plus for us, because whole navigator is a component – r:navigator. That should not be a problem, but this component has no documentation and what is much worse, this component's aim is just to view that simple menu with Guest home, Alfresco home, My home and Company home. Nothing less, nothing more, no editings.So what to do with that crap? Let's do some hacking! You can see my result at following picture, I added one more link:

 

Image and video hosting by TinyPic    Image and video hosting by TinyPic

 

Navigator.jsp is in /jsp/sidebar/ and at start there is just that component:

 <r:navigator id="navigator" activeArea="#{NavigationBean.toolbarLocation}" />

 This component renders ahref links inside divs, like this:

<div id="navigator">
      <div><a href="foo">bar</a></div>
      <div><a href="bar">foo</a></div>
          . . .
</div>

So I need to insert my own container with my link (both styled some way). ActionLink doesn't take 'class' attribute, so I need to inject that attribute with simple javascript:

 <a:booleanEvaluator value="#{BrowseSessionBean.isArchivaceExist}">
    <f:verbatim>
        <div id="navigatorArchivaceBox" class="sidebarButton" style="background-image: url(/alfresco/images/parts/navigator_grey_gradient_bg.gif);">
    </f:verbatim>
    <a:actionLink id="navigatorArchivaceLink" value="Archivace" href="#{BrowseSessionBean.archivaceUrl}"/>
    <f:verbatim>
            <script type="text/javascript">
                   var link = document.getElementById("navigatorArchivaceLink");
                   link.setAttribute("class","sidebarButtonLink");
            </script>
        </div>
    </f:verbatim>
</a:booleanEvaluator>

I personally hate that opening div inside verbatim tag and also that closing div, but what I can do else :-/. So this simple hack added my own link into navigator menu, it's clickable, it's styled, that link works, but that box is not selectable. After deploy this probably look like left picture a few rows higher. All that code is placed inside evaluator, because I need to have destination space accessible, to display this link in menu.

So next thing to do is to deselect all boxes and all links after 'my link' is clicked and also select my box and my link. Sounds simple, but it isn't thanks to 'My Alfresco' link. I'm doing all this stuff only when I'm at the right place (my Archivace space), so I need evaluator:

<a:booleanEvaluator value="#{BrowseSessionBean.isInsideArchivace}">
<f:verbatim>

Inside this evaluator I have simple javascript, which goes through elemnts under navigator container – links and divs – and for each set 'unselected' style:

<script type="text/javascript">
    // disabling 'selected' style at all links
    var links = document.getElementById("navigator").getElementsByTagName('a');
    for(var i=0; i<links.length; i++){
        links[i].setAttribute("class","sidebarButtonLink");
    }

    // disabling 'selected' style at all boxes
    var links = document.getElementById("navigator").getElementsByTagName('div');
    for(var i=0; i<links.length; i++){
        links[i].setAttribute("class","sidebarButton");
        links[i].setAttribute("style","background-image: url(/alfresco/images/parts/navigator_grey_gradient_bg.gif)");
    }

Now it's time to set 'selected' style just for my (selected) link. I know its ids, so I can access them directly through getElementById:

document.getElementById("navigatorArchivaceBox").setAttribute("style","background-image: url(/alfresco/images/parts/navigator_blue_gradient_bg.gif)");
document.getElementById("navigatorArchivaceLink").setAttribute("class","sidebarButtonSelectedLink");

And now all I have to do is 'just' to create evaluator – isInsideArchivace. That is not so hard – just getting current node and asking, if it has wanted aspect ;-).

public boolean getIsInsideArchivace(){
    if(this.getCurrentLocation()==null)return false;
    return this.navigator.getCurrentNode().hasAspect(cz.shmoula.ArchivaceModel.archSummary);
}

Now it's all doomed to work, like on first and second image :-). BUT – 'My Alfresco' is not an ordinary space, it's some virtual space or something, so when I left my 'Archivace' space by clicking on 'My Alfresco', My Alfresco screen is opened, but selected option is still 'Archivace'. What to do? Look at breadcrumb, because when there is node, it's ordinary space. But when there's nothing, it's probably 'My Alfresco' space (if not, it doesn't matter, because it is not my 'Archivace' space) and it's neccessarynot to display 'Archivace' as selected node. Soall that is inside that getCurrentLocation, which fragments are stolen somewhere from Alfresco sources:

 public String getCurrentLocation(){
        List<IBreadcrumbHandler> location = this.navigator.getLocation();
        String name = null;
          if (location.size() != 0){
              for (int i=0; i<location.size(); i++){
                 IBreadcrumbHandler element = location.get(i);
                 if (element instanceof IRepoBreadcrumbHandler){
                    NodeRef nodeRef = ((IRepoBreadcrumbHandler)element).getNodeRef();
                    name = Repository.getNameForNode(this.getNodeService(), nodeRef);
                 }
              }
          }
          return name;
    }

At this time it's all and it works! Ugly and hacky solution, but it works (FF3). Maybe it'll be better to write own component (eg. some tree browsing component), but now I wanted some simple and fast (and really ugly). Oh, I almost forget – this thread helped me a lot!

Playing with titlebar and navigator

My next quest was to change content of titlebar and navigator box. Titlebar was really easy, but navigator box is 'hell itself', because it's r:navigator component and i didn't want to create another component just for adding one more line.

My next quest was to change content of titlebar and navigator box. Titlebar was really easy, but navigator box is 'hell itself', because it's r:navigator component and i didn't want to create another component just for adding one more line.

Titlebar editing is very easy. Final result is on following screenshot:

Image and video hosting by TinyPic

That topmenu is created by a styled a:modeList component with some listItems. ModeList has actionListener set and after listItem is clicked, its value is sent to that listener (which is a big switch). So my first task was to bridge that listener. Original code is placed in NavigationBean and that method is named toolbarLocationChanged. I wrote my own eventListener in 'someBean' this way:

public void toolbarLocationChanged(ActionEvent event){
     UIModeList locationList = (UIModeList)event.getComponent();
     String location = locationList.getValue().toString();
     if(location.equals("archivace")){
      . . .
      }else this.navigator.processToolbarLocation(location, true);

In this piece of code is loaded 'location' – value of listItem (ie companyhome, userhome, archivace… see later) and is compared with identificator of my action.If equals, something happens (see next listing ;-)), else original processToolbarLocation routine in NavigationBean is called.

That something piece of code, which happens in that case is creation of breadcrumb and some informations in NavigationBean are changed, follows here:

List<IBreadcrumbHandler> elements = new ArrayList<IBreadcrumbHandler>(1);
Node archivace = new Node(getArchivaceRef());
elements.add(new NavigationBreadcrumbHandler(archivace.getNodeRef(), archivace.getName()));
this.navigator.setLocation(elements);
this.navigator.setCurrentNodeId(archivace.getId());

But that is not all, you have to inform registered beans that the current area has changed:

UIContextService.getInstance(FacesContext.getCurrentInstance()).areaChanged();

And because the current node is not added to the dispatch context automaticaly, it's needed to add it programaticaly (this was very old bug of Alfresco and in some cases still lasts – forum, jira):

 this.navigator.setupDispatchContext(this.navigator.getCurrentNode());

Last thing to do is to force a navigation to refresh the browse screen breadcrumb:

FacesContext context = FacesContext.getCurrentInstance();
 context.getApplication().getNavigationHandler().handleNavigation(context, null, "browse");

 That's all java coding. Now some jsp: you have to edit file titlebar.jsp in /jsp/parts/ and change actionListener in a:modeList and add another a:listItem as seen on next listing (simplified):

<a:modeList . . . actionListener="#{SomeBean.toolbarLocationChanged}">
      <a:listItem value="archivace" label="Archivace" rendered="#{SomeBean.isArchivaceExist}"/>
</a:modeList>

Ah, I see there is evaluator – isArchivaceExist. It's just an evaluator, which returns true/false – if space I want to view exists, so that listItem is viewed just in case of that space exists.

 

As I can see, it'll be better to move navigator hacks to next blogpost.

Vybírám licenci pro geoANDhash

Když jsem doposud páchal jakýkoliv projekt, většinou jsem si nechal zdrojáky pro sebe a výslednou podobu jsem nějak vypustil mezi širokou veřejnost, šiř se jak šiř. Teď jsem však dospěl do fáze, kdy bych se rád nějakým způsobem podělil i o zdrojový kód, aby se mohli připojit další, resp. chcisi nechat projekt hostovat na google code a při registraci je potřeba uvést, pod jakou licencí je daný kód možné šířit. Proto bych chtěl vyzkoumat, která licence by pro mě byla nejvhodnější.

Když jsem doposud páchal jakýkoliv projekt, většinou jsem si nechal zdrojáky pro sebe a výslednou podobu jsem nějak vypustil mezi širokou veřejnost, šiř se jak šiř. Teď jsem však dospěl do fáze, kdy bych se rád nějakým způsobem podělil i o zdrojový kód, aby se mohli připojit další, resp. chcisi nechat projekt hostovat na google code a při registraci je potřeba uvést, pod jakou licencí je daný kód možné šířit. Proto bych chtěl vyzkoumat, která licence by pro mě byla nejvhodnější.

Nejvhodnější vlastnosti by pro mě měla zřejmě Creative Commons – Attribution-Share Alike 3.0 Unported, která povoluje šířit a modifikovat za podmínek, že produkt bude označen dle mých podmínek a pokud bude pozměněn, musí být dále šířen pod toutéž licencí, nebo licencí kompatibilní.

http://www.czilla.cz/podpora/shrnuti-mpl.html

http://www.root.cz/clanky/gnugpl-pravni-rozbor-licence/

http://www.martinvseticka.eu/index.php?sekce=browse&page=137

http://www.gnu.cz/article/30/

http://cs.wikipedia.org/wiki/BSD_licence

http://www.it-joker.cz/Pocitace-weby/71-Obsah-zdarma-a-licence,-aneb-jak-se-v-nich-vyznat.html

Mimetype detection in upload component

I posted short topic about my way to uploading files to Alfresco some time before. Now I turned all that code into my own component and added it to Tag Library and also added mimetype detection and some other amazing stuff. I'll try to describe some facts about my implementation in this blogpost, so be encouraged to keep reading ;-).

I posted short topic about my way to uploading files to Alfresco some time before. Now I turned all that code into my own component and added it to Tag Library and also added mimetype detection and some other amazing stuff. I'll try to describe some facts about my implementation in this blogpost, so be encouraged to keep reading ;-).

I'm not going to describe how to build own component, there are many tutorials on web (for example here or here) and it's much simplier than stuff I'm going to write about (many ughly javascript code). So let's begin.Firstly, thanks to component,jsp code is simplified. I compressed whole code into component (form inputs, labels, also js libraries includes), so my code lookslike this (note that javascript part is optional and is there just to disable OK button on page load; also mimetype selector is optional).

<%@ taglib uri="http://www.shmoula.cz/jsf/component/tags" prefix="shmoula" %>

<script type="text/javascript">
function pageLoaded(){
    document.getElementById("dialog:finish-button").disabled = true;
}
window.onload = pageLoaded;
</script>

. . .

    <h:inputHidden id="fileId" value="#{SlowUpload.fileId}" />
    <shmoula:upload label="soubor" />
    <r:mimeTypeSelector id="mime-type" value="#{SlowUpload.mimeType}" />

. . .

FileId parameter does still the same thing – it connects get data with post data – identificator is created and then AJAX call is made, in which goes this id and filename to servelt, which creates a new FileBean and also get mimetype from filename and send it back. You can see this snippet on following listing.

 public void doGet(HttpServletRequest request,HttpServletResponse response)throws ServletException, IOException{
       PrintWriter out = response.getWriter();
       
       try{
           // creating a new bean for fileinfo storing and also setting some info
           this.fileUploadBean = new FileUploadBean();
           this.uploadId = request.getParameter("uploadid");
           String filename = request.getParameter("filename");

           // fetching mimetypeService from SlowUpload bean; more info follows
           SlowUpload slowUpload = (SlowUpload)request.getSession().getAttribute("SlowUpload");
           MimetypeService mimetypeService = slowUpload.getMimetypeService();
       
           // guessing and returning mimetype
           // if mimetype is not recognized, application/octet-stream is returned

           out.print(mimetypeService.guessMimetype(filename));
           
       }catch(Exception e){
           out.print("FALSE");
       }
}

MimetypeService must be injected into SlowUpload bean, so I need some Setters in my class for that and definition in Faces config:

 <managed-bean>
       <managed-bean-name>SlowUpload</managed-bean-name>
       <managed-bean-class>cz.shmoula.SlowUpload</managed-bean-class>
       <managed-bean-scope>session</managed-bean-scope>
. . .
       <managed-property>
           <property-name>mimetypeService</property-name>
           <value>#{MimetypeService}</value>
       </managed-property>
. . .
   </managed-bean>

 Now onComplete function is called thanks to prototype library AJAX calling. In this function a right option in select box is selected just through a simple loop, as you can see:

function callbackFunction(originalRequest){
    var vystup = new String(originalRequest.responseText);
    
    if(vystup=="FALSE"){
        rollback(1);
        alert("Chyba pri uploadu");
    }else{
        var select = document.getElementById("dialog:dialog-body:mime-type");
        for(i=0;i<select.length;i++){
            var selectVal = new String(select.options[i].value);
            if(selectVal.match(vystup)!=null){
                select.options[i].selected = true;
                select.selectedIndex = i;    
                break;
            }
        }
    }
}

And after all this whole formular is sent to servlet via POST method. All this is described in previous post, so you can check it out there. But there is one change – servlet returns success of operation inside hidden input. So I changed servlet this way:

response.setContentType("text/html");
PrintWriter out = response.getWriter();
out.println(". . .<input type="hidden" id="iframe_status" value=""+this.fileUploadBean.getFileName()+"" />. . .");

On client side is after (un-)successfully file upload called handle_upload() function, which gets value from included iFrame and decides that operation was or was not successfull and call appropriate actions:

function handle_upload(){
    var doc = getIframeDocument();
    var filename = doc.getElementById("iframe_status").value;
   
    if(filename != "FALSE"){
        var fileNameInput = document.getElementById('dialog:dialog-body:fileName');
        if(fileNameInput!=null)
            fileNameInput.value = filename;
        checkButtonState();
    }else{
        rollback(1);
        alert("Chyba pri uploadu!");
    }
}

CheckButtonState function does nothing else, than enable OK button for complete submit all those information (if some other conditions came true) and rollback function sets form target to original target – …/dialog/container.jsp.

That's all folks! Simplified procedure of my component activity. I wish I have not to write these hacks and all those things are accessible by developer in alfresco (they are there, but you can't use them outside specified containers or-how-to-name-that) some simple way. Maybe in future I hope!