<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Cygni&#187; Stacktrace</title>
	<atom:link href="http://cygni.se/kategori/stacktrace/feed/" rel="self" type="application/rss+xml" />
	<link>http://cygni.se</link>
	<description>expertis inom agil systemutveckling på moderna plattformar</description>
	<lastBuildDate>Mon, 21 May 2012 09:02:55 +0000</lastBuildDate>
	<language>sv</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0.1</generator>
		<item>
		<title>pushState + ajax = pjax</title>
		<link>http://cygni.se/2012/05/21/pushstate-ajax-pjax/</link>
		<comments>http://cygni.se/2012/05/21/pushstate-ajax-pjax/#comments</comments>
		<pubDate>Mon, 21 May 2012 09:02:55 +0000</pubDate>
		<dc:creator>Nathalie Sandström</dc:creator>
				<category><![CDATA[Stacktrace]]></category>
		<category><![CDATA[ajax]]></category>
		<category><![CDATA[frontend]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[jquery]]></category>
		<category><![CDATA[pjax]]></category>

		<guid isPermaLink="false">http://cygni.se/?p=4188</guid>
		<description><![CDATA[HTML5&#8242;s History API kom med pushState vilket kort och gott låter utvecklaren manipulera browser-historiken genom att manuellt peta in URL:ar på historikstacken. pushState är användbart för tillfällen då endast delar av webbsidan behöver laddas om, där det tidigare inte varit möjligt att samtidigt tala om för browsern att byta URL. Med pushState förändrar du URL:en ...]]></description>
			<content:encoded><![CDATA[<p>HTML5&#8242;s <a href="http://diveintohtml5.info/history.html">History API</a> kom med pushState vilket kort och gott låter utvecklaren manipulera browser-historiken genom att manuellt peta in URL:ar på historikstacken. pushState är användbart för tillfällen då endast delar av webbsidan behöver laddas om, där det tidigare inte varit möjligt att samtidigt tala om för browsern att byta URL. Med pushState förändrar du URL:en på sidor med dynamiskt innehåll vilket lämnar användaren med en snabbare laddning och fungerande bakåt- och framåtknapp i browsern.</p>
<pre class="brush: jscript; title: ;">
history.pushState(null, &quot;dinosaurs&quot;, dinosaurs.html);
</pre>
<p>Här lägger vi till ett ny historik-post (<code>dinosaurs.html</code>) på stacken och passar samtidigt på att döpa om sidan till &#8221;dinosaurs&#8221;.</p>
<p><a href="http://pjax.heroku.com/">pjax</a> är ett jQuery-bibliotek som utnyttjar pushState och, som de själva säger, ökar browsingupplevelsen &#8211; <em>nothing more</em>. </p>
<p>pjax kan implementeras på ett flertal sätt, här följer ett:</p>
<pre class="brush: jscript; title: ;">
&lt;script type=&quot;text/javascript&quot;&gt;
    &quot;#nav change&quot;: function(el) {
        $.pjax({
            url: el.find(&quot;:selected&quot;).data(&quot;href&quot;),
        	container: &quot;#main&quot;
        });
    }
&lt;/script&gt;

&lt;div id=&quot;main&quot;&gt;
    Hello dinosaurs!
&lt;/div&gt;

&lt;select id=&quot;nav&quot;&gt;
    &lt;option data-href=&quot;/home&quot;&gt;home&lt;/option&gt;
    &lt;option data-href=&quot;/dinosaurs&quot; selected=&quot;selected&quot;&gt;dinosaurs&lt;/option&gt;
&lt;/select&gt;
</pre>
<p>I koden anropas funktionen <code>pjax()</code> när användaren byter värde i en select-box. pjax-anropet fungerar i stort sätt som ett vanligt ajax-anrop där det svar vi får tillbaka skrivs ut i den main-container vi plockar ut med selektorn <code>"#main"</code>. </p>
<p>Det som slutligen, implicit och per default, sker är ett anorp till pushState där vi lägger till URL:en på stacken. Anropet ser ut något i stil med: </p>
<pre class="brush: jscript; title: ;">
history.pushState(null, $(data).filter('title').text(), '/dinosaurs')
</pre>
<p>Ett smidigt sätt att öka upplevelsen för användaren. </p>
<p>Vill du labba med pjax hittar du <a href="https://github.com/defunkt/jquery-pjax">koden här</a> och för ett hands-on-exempel kan du titta närmare på <a href="https://github.com/defunkt/jquery-pjax/tree/heroku">den här koden</a>. </p>

	Tags: <a href="http://cygni.se/taggar/ajax/" title="ajax" rel="tag">ajax</a>, <a href="http://cygni.se/taggar/frontend/" title="frontend" rel="tag">frontend</a>, <a href="http://cygni.se/taggar/javascript/" title="javascript" rel="tag">javascript</a>, <a href="http://cygni.se/taggar/jquery/" title="jquery" rel="tag">jquery</a>, <a href="http://cygni.se/taggar/pjax/" title="pjax" rel="tag">pjax</a><br />
]]></content:encoded>
			<wfw:commentRss>http://cygni.se/2012/05/21/pushstate-ajax-pjax/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>jQuery Vector Maps</title>
		<link>http://cygni.se/2012/05/14/jquery-vector-maps/</link>
		<comments>http://cygni.se/2012/05/14/jquery-vector-maps/#comments</comments>
		<pubDate>Mon, 14 May 2012 10:26:58 +0000</pubDate>
		<dc:creator>Lars Hendahl</dc:creator>
				<category><![CDATA[Stacktrace]]></category>
		<category><![CDATA[frontend]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[jquery]]></category>
		<category><![CDATA[svg]]></category>

		<guid isPermaLink="false">http://cygni.se/?p=4179</guid>
		<description><![CDATA[Att skapa interaktiva kartor är ett vanligt förekommande behov för webbsajter. Vill man dessutom undvika en flash-lösning och inte lägga ner arbete på en mer statisk lösning finns nu möjligheten att använda jQuery Vector Maps (JQVMap). JQVMap är en jQuery-plugin som gör kartor med vektorbaserad grafik. Den använder Scalable Vector Graphics (SVG) för moderna webbläsare ...]]></description>
			<content:encoded><![CDATA[<p>Att skapa interaktiva kartor är ett vanligt förekommande behov för webbsajter. Vill man dessutom undvika en flash-lösning och inte lägga ner arbete på en mer statisk lösning finns nu möjligheten att använda <a href="http://jqvmap.com/" target="_blank">jQuery Vector Maps</a> (JQVMap).</p>
<p>JQVMap är en <a href="http://jquery.com" target="_blank">jQuery</a>-plugin som gör kartor med vektorbaserad grafik. Den använder <a href="https://developer.mozilla.org/en/SVG/Tutorial" target="_blank">Scalable Vector Graphics (SVG)</a> för moderna webbläsare som Firefox, Safari, Chrome, Opera och Internet Explorer 9. Legacy-stöd för äldre versioner av Internet Explorer 6-8 tillhandahålls via VML.</p>
<p><a href="http://jqvmap.com/" target="_blank"><img class="size-medium wp-image-4183" title="http://jqvmap.com/" src="http://cygni.se/wp-uploads/2012/05/Skärmavbild-2012-05-11-kl.-09.09.16-300x182.png" alt="" width="300" height="182" /></a></p>
<p>Det medkommer ett antal kartor över världen, USA och Europa som är färdiga att använda. Det finns flera konfigurationsmöjligheter som färger, kantlinjer och opacities.</p>

	Tags: <a href="http://cygni.se/taggar/frontend/" title="frontend" rel="tag">frontend</a>, <a href="http://cygni.se/taggar/javascript/" title="javascript" rel="tag">javascript</a>, <a href="http://cygni.se/taggar/jquery/" title="jquery" rel="tag">jquery</a>, <a href="http://cygni.se/taggar/svg/" title="svg" rel="tag">svg</a><br />
]]></content:encoded>
			<wfw:commentRss>http://cygni.se/2012/05/14/jquery-vector-maps/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Maven 2 &#8211; phases of the default lifecycle</title>
		<link>http://cygni.se/2012/04/26/maven-2-phases-of-the-default-lifecycle/</link>
		<comments>http://cygni.se/2012/04/26/maven-2-phases-of-the-default-lifecycle/#comments</comments>
		<pubDate>Thu, 26 Apr 2012 14:52:11 +0000</pubDate>
		<dc:creator>Nathalie Sandström</dc:creator>
				<category><![CDATA[Stacktrace]]></category>
		<category><![CDATA[java]]></category>
		<category><![CDATA[maven]]></category>

		<guid isPermaLink="false">http://cygni.se/?p=3921</guid>
		<description><![CDATA[Maven, som tillämpar en livscykelbaserad ansats, kommer med en tydligt fördefinierad bygg- och distribueringsprocess där användaren endast behöver lära sig ett litet antal kommandon för att bygga sin artefakt. I POM:en talar vi om hur projektet ska se ut och vad det ska innehålla. Här definierar vi upp hur projektet paketeras och vilka beroenden det ...]]></description>
			<content:encoded><![CDATA[<p>Maven, som tillämpar en livscykelbaserad ansats, kommer med en tydligt fördefinierad bygg- och distribueringsprocess där användaren endast behöver lära sig ett litet antal kommandon för att bygga sin artefakt. I POM:en talar vi om hur projektet ska se ut och vad det ska innehålla. Här definierar vi upp hur projektet paketeras och vilka beroenden det har. Hur Maven sedan hanterar projektet när det utför sitt jobb bestäms genom mål (goals) knutna till ett gäng bestämda faser (phases) i olika livscykler (lifecycles).</p>
<p>Kort och gott innebär detta att du, när du kör ett Mavenkommando, talar om för Maven att gå igenom ett antal faser och att exekvera de mål som hör till varje fas.</p>
<p><img src="http://cygni.se/wp-uploads/2012/01/levels.png" alt="Illustration över Mavens olika nivåer" title="levels" width="404" height="479" class="size-full wp-image-3953" /><br />
<em>Illustration över Mavens olika nivåer</em></p>
<p>Maven har tre inbyggda livscykler:</p>
<ul>
<li><em>default</em> (även kallad build) som hanterar deployment</li>
<li><em>clean</em> som sköter rensning av projekt</li>
<li><em>site</em> som hanterar projektdokumentering</li>
</ul>
<p>Var och en av dessa cykler innehåller ett antal <em>faser</em> som representerar ett specifikt steg i cykeln. Exempelvis innehåller defaultcykeln fasen <em>compile</em> som ansvarar för kompilering av källkoden. Trots att varje fas har en specifik uppgift kan sättet den utför sin uppgift på variera då det är de mappade <em>målen</em> som i slutändan bestämmer vad som faktiskt sker. Vilka mål som knyts till vilken fas bestäms dels och framöverallt genom sättet artefakten paketerats men också genom de plugins som sugs in i projektet.</p>
<p>Som bilden ovan visar kan ett mål kan vara knutet till ett, flera eller inga faser precis som en fas kan innehålla noll eller flera mål. Ett fristående mål kan exekveras utanför livscykeln samtidigt som ett mål mappat mot flera faser körs en gång för varje mappning. Faser innehållandes multipla mål exekverar dessa i samma ordning som de deklarerats i POM:en. Däremot kommer en fas utan några mål aldrig att exekveras.</p>
<p>Defaultcyklen &#8211; för många användare den mest betydelsefulla cykeln då den fungerar som en generell modell för en applikations byggprocess &#8211; innehåller sammanlagt 23 faser. Nedan listar jag de mest framträdande av dessa:</p>
<p><strong>Validate</strong><br />
Bekräftar att projektet är korrekt och att all information som behövs för att slutföra ett bygge finns tillgänligt.</p>
<p><strong>Compilie</strong><br />
Komplilerar källkoden.</p>
<p><strong>Test</strong><br />
Testar den kompilerade koden mot uppsatta tester.</p>
<p><strong>Package</strong><br />
Paketerar den kompilerade koden till ett distribuerbart format (exempelvis .jar).</p>
<p><strong>Integration-test</strong><br />
Om så är nödvändigt läggs den paketerade koden ut i en miljö anpassad för att köra integrationstester i.</p>
<p><strong>Verify</strong><br />
Kör uppsatta kontroller för verifiering av paketets giltighet samt kontrollerar att paketet möter alla kvalitetskriterier.</p>
<p><strong>Install</strong><br />
Installerar paketet i det lokala repot och kan nu användas som ett beroende i andra projekt lokalt.</p>
<p><strong>Deploy</strong><br />
Kopierar det slutgiltiga paketet till ett remote repo för delning med andra projekt och utvecklare.</p>
<p>Utöver dessa faser tillkommer mellanfaser vilka bland annat hanterar förberedelser som att kopiera och flytta resurser till rätt kataloger samt post-process-steg som att städa upp efter körda tester. <a href="http://maven.apache.org/guides/introduction/introduction-to-the-lifecycle.html#Lifecycle_Reference" target="_blank">Här hittar ni den kompletta listan över faser</a>.</p>

	Tags: <a href="http://cygni.se/taggar/java/" title="java" rel="tag">java</a>, <a href="http://cygni.se/taggar/maven/" title="maven" rel="tag">maven</a><br />
]]></content:encoded>
			<wfw:commentRss>http://cygni.se/2012/04/26/maven-2-phases-of-the-default-lifecycle/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>En introduktion till JavaScriptMVC</title>
		<link>http://cygni.se/2012/04/11/en-introduktion-till-javascriptmvc/</link>
		<comments>http://cygni.se/2012/04/11/en-introduktion-till-javascriptmvc/#comments</comments>
		<pubDate>Wed, 11 Apr 2012 08:53:34 +0000</pubDate>
		<dc:creator>Nathalie Sandström</dc:creator>
				<category><![CDATA[Stacktrace]]></category>
		<category><![CDATA[documentjs]]></category>
		<category><![CDATA[frontend]]></category>
		<category><![CDATA[funcunit]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[javascriptmvc]]></category>
		<category><![CDATA[jquery]]></category>
		<category><![CDATA[jquerymq]]></category>
		<category><![CDATA[selenium]]></category>
		<category><![CDATA[stealjs]]></category>
		<category><![CDATA[systemutveckling]]></category>

		<guid isPermaLink="false">http://cygni.se/?p=4122</guid>
		<description><![CDATA[Att skapa och kanske framförallt bibehålla en schyst, begriplig struktur när man kodar JavaScript kan vara en besvärlig uppgift. Stora, dynamiska webbprojekt innebär ofta en stor, JS-tung kodbas som – allteftersom funktionaliteten utökas – kan bli mer och mer svårhanterlig. Koden saknar många gånger organisation, sprids ut och kan i slutändan leda till onödigt invecklad ...]]></description>
			<content:encoded><![CDATA[<p>Att skapa och kanske framförallt bibehålla en schyst, begriplig struktur när man kodar JavaScript kan vara en besvärlig uppgift. Stora, dynamiska webbprojekt innebär ofta en stor, JS-tung kodbas som – allteftersom funktionaliteten utökas – kan bli mer och mer svårhanterlig.  Koden saknar många gånger organisation, sprids ut och kan i slutändan leda till onödigt invecklad kod som blir svår att underhålla och utöka.  </p>
<p><a href="http://javascriptmvc.com/" target="_blank">JavaScriptMVC</a> (JMVC) är ett open source-ramverk med motivationen att hjälpa dig som klientutvecklare att bygga strukturerade, skalbara JavaScript-applikationer av hög kvalitet. Byggt ovanpå <a href="http://jquery.com/" target="_blank">jQuery</a> erbjuder JMVC en samling <em>best-practices</em> och verktyg där man plockat ut det bästa från jQuery i avsikt att bringa ordning i röran: <a href="http://javascriptmvc.com/docs.html#!jquerymx" target="_blank">jQueryMX</a>, <a href="http://javascriptmvc.com/docs.html#!stealjs" target="_blank">StealJS</a>, <a href="http://javascriptmvc.com/docs.html#!FuncUnit" target="_blank">FuncUnit</a> och <a href="http://javascriptmvc.com/docs.html#!DocumentJS" target="_blank">DocumentJS</a>.<span id="more-4122"></span></p>
<h3>jQueryMX</h3>
<p><a href="http://javascriptmvc.com/docs.html#!jquerymx" target="_blank">jQueryMX</a> består av ett gäng jQuery-bibliotek vars syfte är att tillhandahålla den struktur och organisation man många gånger saknar i jQuery-tunga applikationer. jQueryMX kommer bland annat med specialevents som <em>drag-and-drop</em>, <em>DOM extensions</em> och <em>language helpers</em> som förenklar hantering av JavaScript-data.</p>
<p>Utöver detta inför jQueryMX även MVC-tänket i JavaScript med sina <code>$.Model-</code>, <code>$.View-</code> och <code>$.Controller-</code>plugins. Dessa olika delar kan användas tillsammans eller separat vilket innebär att du endast inkluderar de plugins du faktiskt kommer att ha användning för.</p>
<p>MVC-upplägget fungerar enligt förväntan:</p>
<ul>
<li>Modellen kapslar in service- och datalagret och kommunicerar via JSON-baserade REST-anrop.</li>
<li>Vyn renderar modelldata som hämtats från servern.</li>
<li>Controllern lyssnar på events och sköter kommunikation mellan modellen och vyn.</li>
</ul>
<h3>StealJS</h3>
<p><a href="http://javascriptmvc.com/docs.html#!stealjs" target="_blank">StealJS</a> är en samling verktyg som gör det enkelt att bygga, paketera och dela JavaScript-applikationer. Verktygen kommer med en mängd trevliga egenskaper:</p>
<ul>
<li>StealJS är bra på <em>Dependency Management</em>.</li>
<li>StealJS hjälper dig bygga ihop dina JS- och CSS-filer till en enda komprimerad produktionsfil.</li>
<li>StealJS kan användas för att generera projektstrukturer.</li>
<li>StealJS kommer med stöd för SVN och GIT.</li>
<li>StealJS möjliggör <em>code cleaning</em> och validering via <a href="http://www.jslint.com/" target="_blank">JSLint</a>.</li>
<li>Och som en liten bonus kan StealJS <a href="https://developers.google.com/webmasters/ajax-crawling/docs/getting-started?hl=sv-SE" target="_blank">göra din AJAX-app <em>crawlable</em></a>.</li>
</ul>
<h3>FuncUnit</h3>
<p><a href="http://javascriptmvc.com/docs.html#!FuncUnit" target="_blank">FuncUnit</a> är ett testramverk med ambitionen att göra enhetstestning och funktionell testning av webbapplikationer enklare och  &#8211; som de själva säger &#8211; roligare! Med en jQuery-liknande syntax skriver, kör och debuggar du dina tester direkt i browsern (fungerar för IE 6+, FF 2+, Safari 4+, Opera 9+ och Chrome) och samma tester kan, via <a href="http://seleniumhq.org/" target="_blank">Selenium</a>, också automatiseras. FuncUnit stödjer simulering av <em>user actions</em> såsom <em>typing</em>, <em>clicking</em>, <em>dragging </em>och <em>scrolling</em>.</p>
<p>Nedanstående kod, vilken testar att en <em>AutoSuggest</em> returnerar fem resultat, får fungera som exempel på ramverkets hyfsat okomplicerade syntax:</p>
<pre class="brush: jscript; title: ;">
module(&quot;autosuggest&quot;,{
 setup: function() {
   S.open('autosuggest.html')
 }
});

test(&quot;JavaScript results&quot;,function(){
 S('input').click().type(&quot;JavaScript&quot;)

 // wait until we have some results
 S('.autocomplete_item').visible(function(){
   equal( S('.autocomplete_item').size(), 5, &quot;there are 5 results&quot;)
 })
});
</pre>
<h3>DocumentJS</h3>
<p><a href="http://javascriptmvc.com/docs.html#!DocumentJS" target="_blank">DocumentJS</a> tillhandahåller, precis som namnet avslöjar, verktyg för dokumentering av JavaScript-kod. DocumentJS hjälper dig generera, organisera, granska och underhålla din dokumentation och, precis som i alla andra delar av JavaScriptMVC, ligger fokus på användarvänlighet och enkelhet. </p>

	Tags: <a href="http://cygni.se/taggar/documentjs/" title="documentjs" rel="tag">documentjs</a>, <a href="http://cygni.se/taggar/frontend/" title="frontend" rel="tag">frontend</a>, <a href="http://cygni.se/taggar/funcunit/" title="funcunit" rel="tag">funcunit</a>, <a href="http://cygni.se/taggar/javascript/" title="javascript" rel="tag">javascript</a>, <a href="http://cygni.se/taggar/javascriptmvc/" title="javascriptmvc" rel="tag">javascriptmvc</a>, <a href="http://cygni.se/taggar/jquery/" title="jquery" rel="tag">jquery</a>, <a href="http://cygni.se/taggar/jquerymq/" title="jquerymq" rel="tag">jquerymq</a>, <a href="http://cygni.se/taggar/selenium/" title="selenium" rel="tag">selenium</a>, <a href="http://cygni.se/taggar/stealjs/" title="stealjs" rel="tag">stealjs</a>, <a href="http://cygni.se/taggar/systemutveckling/" title="systemutveckling" rel="tag">systemutveckling</a><br />
]]></content:encoded>
			<wfw:commentRss>http://cygni.se/2012/04/11/en-introduktion-till-javascriptmvc/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>{less} &#8211; CSS</title>
		<link>http://cygni.se/2012/04/02/less-css/</link>
		<comments>http://cygni.se/2012/04/02/less-css/#comments</comments>
		<pubDate>Mon, 02 Apr 2012 09:00:45 +0000</pubDate>
		<dc:creator>Lars Hendahl</dc:creator>
				<category><![CDATA[Stacktrace]]></category>
		<category><![CDATA[css]]></category>
		<category><![CDATA[css3]]></category>
		<category><![CDATA[frontend]]></category>
		<category><![CDATA[html]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[less]]></category>
		<category><![CDATA[node.js]]></category>
		<category><![CDATA[rhino]]></category>

		<guid isPermaLink="false">http://cygni.se/?p=4064</guid>
		<description><![CDATA[Att konstruera och underhålla CSS-strukturer och instruktioner för större sajter kan vara nog så tidskrävande. CSS-dokumentationen i sig själv ger inget eget stöd för variabler. Detta leder ofta till att man måste ange samma CSS-värden upprepade gånger i ett CSS-dokument. Men det finns hjälp att tillgå, låt oss ta en titt på det dynamiska CSS-språket ...]]></description>
			<content:encoded><![CDATA[<p>Att konstruera och underhålla <a href="http://www.w3.org/Style/CSS/" target="_blank">CSS</a>-strukturer och instruktioner för större sajter kan vara nog så tidskrävande. CSS-dokumentationen i sig själv ger inget eget stöd för variabler. Detta leder ofta till att man måste ange samma CSS-värden upprepade gånger i ett CSS-dokument.</p>
<p>Men det finns hjälp att tillgå, låt oss ta en titt på det dynamiska CSS-språket <a href="http://lesscss.org/" target="_blank">{less}</a> som genom förkompilering ger oss möjlighet att använda <code>variables</code>, <code>mixins</code>, <code>operations</code> och <code>functions</code>.<br />
<span id="more-4064"></span></p>
<h3>Ange variabler som du kan återanvända</h3>
<pre class="brush: css; title: ;">
// instruktion i less
@color: #4D926F;
#header {color: @color;}
h2 {color: @color;}
</pre>
<pre class="brush: css; title: ;">
/*kompilerat CSS Resultat*/
#header {color: #4D926F;}
h2 {color: #4D926F;}
</pre>
<h3>Mixins, inbäddning av css värden:</h3>
<pre class="brush: css; title: ;">
// instruktion i less
.rounded-corners (@radius: 5px) {
    border-radius:@radius;
    -webkit-border-radius: @radius;
    -moz-border-radius: @radius;
}

#header {.rounded-corners}
#footer {.rounded-corners(10px);}
</pre>
<pre class="brush: css; title: ;">
/*kompilerat CSS Resultat*/
#header {
    border-radius: 5px;
    -webkit-border-radius: 5px;
    -moz-border-radius: 5px;
}

#footer {
     border-radius: 10px;
    -webkit-border-radius: 10px;
    -moz-border-radius: 10px;
}
</pre>
<h3>Nästlade regler</h3>
<pre class="brush: css; title: ;">
// instruktion i less
#header {
    h1 {
        font-size: 26px;
        font-weight: bold;
    }
    p {
        font-size: 12px;
        a {
            text-decoration: none;
            &amp;:hover {
                border-width: 1px
            }
        }
    }
}
</pre>
<pre class="brush: css; title: ;">
/*kompilerat CSS Resultat*/
#header h1 {
    font-size: 26px;
    font-weight: bold;
}
#header p {font-size: 12px;}
#header p a {text-decoration: none;}
#header p a:hover {border-width: 1px;}
</pre>
<h3>Operations and functions</h3>
<p>Att hantera relativa fontstorlekar i procent beräknat utifrån pixlar är ett vanligt case. Vi utgår från en basstorlek på 13px och skapar en funktion som returnerar ett procenttal utifrån önskad pixel- och basstorlek:</p>
<pre class="brush: css; title: ;">
// instruktion i less
@basefontsize: 13;

.fontresizer(@fontsize: 13px)  {
    font-size: percentage(@fontsize/@basefontsize);
}
.classx { .fontresizer(); }
</pre>
<pre class="brush: css; title: ;">
/*kompilerat CSS Resultat*/
.classx{ font-size: 100%;}
</pre>
<pre class="brush: css; title: ;">
// instruktion i less
.classx{ .fontresizer(20px);}
</pre>
<pre class="brush: css; title: ;">
/*kompilerat CSS Resultat*/
.classx{font-size: 153.846%;}
</pre>
<p>Ett annat vanligt förekommande behov är att reducera instruktioner för så kallade imagesprite-bakgrunder</p>
<pre class="brush: css; title: ;">
// instruktion i less
.sprite(@offset-x: 0, @offset-y: 0) {
    background: url(&quot;../sprites/icons.png&quot;) scroll no-repeat @offset-x @offset-y;
}
.classx {.sprite(100%, -100px);
}
</pre>
<pre class="brush: css; title: ;">
/*kompilerat CSS Resultat*/
.classx{ background: url(&quot;../sprites/icons.png&quot;) scroll no-repeat 100% -100px;}
</pre>
<h3>Installera och använd {less}</h3>
<p>Less kan användas såväl från klienten (Chrome, Safari och Firefox för lokal utveckling)  som från servern med <a href="http://nodejs.org/" target="_blank">Node.js</a> och <a href="http://www.mozilla.org/rhino/" target="_blank">Rhino</a>. Använder du Maven rekommenderar jag <a href="http://mojo.codehaus.org/lesscss-maven-plugin/">denna plugin</a> för kompilering av {less}-resurser till CSS-filer.</p>
<p>Som Mac-användare kan du även använda {less}-appen från <a href="http://incident57.com/less/" target="_blank">CodeKit</a> i din lokala utvecklingsmiljö</p>

	Tags: <a href="http://cygni.se/taggar/css/" title="css" rel="tag">css</a>, <a href="http://cygni.se/taggar/css3/" title="css3" rel="tag">css3</a>, <a href="http://cygni.se/taggar/frontend/" title="frontend" rel="tag">frontend</a>, <a href="http://cygni.se/taggar/html/" title="html" rel="tag">html</a>, <a href="http://cygni.se/taggar/javascript/" title="javascript" rel="tag">javascript</a>, <a href="http://cygni.se/taggar/less/" title="less" rel="tag">less</a>, <a href="http://cygni.se/taggar/node-js/" title="node.js" rel="tag">node.js</a>, <a href="http://cygni.se/taggar/rhino/" title="rhino" rel="tag">rhino</a><br />
]]></content:encoded>
			<wfw:commentRss>http://cygni.se/2012/04/02/less-css/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Moduler i JavaScript med CommonJS</title>
		<link>http://cygni.se/2012/03/26/moduler-i-javascript-med-commonjs/</link>
		<comments>http://cygni.se/2012/03/26/moduler-i-javascript-med-commonjs/#comments</comments>
		<pubDate>Mon, 26 Mar 2012 14:00:27 +0000</pubDate>
		<dc:creator>Rudolf Hersén</dc:creator>
				<category><![CDATA[Stacktrace]]></category>
		<category><![CDATA[commonjs]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[nodejs]]></category>

		<guid isPermaLink="false">http://cygni.se/?p=4045</guid>
		<description><![CDATA[JavaScript är ett av våra mest underskattade programmeringsspråk. Detta beror på flera saker; det har förmodligen skrivits fler fulhack i JavaScript än i något annat språk, möjligtvis med undantag för Perl. Dessutom har JavaScript några rejäla skönhetsfläckar. De flesta brukar uppröras av jämförelseoperatorerna som ibland gör oväntade typkonverteringar. Personligen tycker jag att avsaknaden av ett ...]]></description>
			<content:encoded><![CDATA[<p>JavaScript är ett av våra mest underskattade programmeringsspråk. Detta beror på flera saker; det har förmodligen skrivits fler fulhack i JavaScript än i något annat språk, möjligtvis med undantag för Perl. Dessutom har JavaScript några rejäla skönhetsfläckar. De flesta brukar uppröras av jämförelseoperatorerna som ibland gör oväntade typkonverteringar. Personligen tycker jag att avsaknaden av ett modulsystem är värre.</p>
<p><a target="_blank" href="http://www.commonjs.org/">CommonJS</a> är ett initiativ startat för tre år sedan under namnet ServerJS av Kevin Dangoor. Det syftar till att göra JavaScript till ett seriöst alternativ som serverplattform. CommonJS innehåller ett antal API-specifikationer, exempelvis för filsystemaccess, hantering av binärdata, kommandoradsargument och utmatning till konsol. Dessutom finns en specifikation för modulhantering: CommonJS Modules. Enligt denna specifikation publicerar man variabler och funktioner med <code>exports</code> och importerar dem med <code>require</code>. Så här kan en modul se ut:</p>
<p><strong><code>movieFinder.js</code></strong></p>
<pre class="brush: jscript; title: ;">
var priv = [];

exports.add = function (item) {
    priv.push(item);
};

exports.findAll = function () {
    return priv;
};
</pre>
<p>Variabeln <code>priv</code> är inte tillgänglig utanför modulen. Det är däremot funktionerna <code>add</code> och <code>findAll</code>, eftersom de lagts till objektet <code>exports</code>. Om en modul behöver importera en annan görs det med <code>require</code>:</p>
<p><strong><code>movieLister.js</code></strong></p>
<pre class="brush: jscript; title: ;">
var finder = require(&quot;./movieFinder&quot;);

exports.moviesDirectedBy = function (arg) {
    var hasDirector = function (movie) {
        return movie.getDirector() === arg;
    };

    return finder.findAll().filter(hasDirector);
};
</pre>
<p>Dessa två moduler kommer bara att finnas i ett exemplar vardera. Om man istället behöver en klass där man kan instansiera objekt tilldelar man en konstruktor till <code>exports</code>:</p>
<p><strong><code>Movie.js</code></strong></p>
<pre class="brush: jscript; title: ;">
var constructor = function (title, director) {
    return {
        getTitle: function () {
            return title;
        },

        getDirector: function () {
            return director;
        },

        toString: function () {
            return title + &quot; by &quot; + director;
        }
    };
};

module.exports = constructor;
</pre>
<p>Notera att det här är ett av många sätt att skriva konstruktorer i JavaScript. Douglas Crockfords <a target="_blank" href="http://www.amazon.com/exec/obidos/ASIN/0596517742/wrrrldwideweb">JavaScript: The Good Parts</a> har ett helt kapitel om detta. Huvudmodulen kan sedan se ut så här:</p>
<p><strong><code>main.js</code></strong></p>
<pre class="brush: jscript; title: ;">
var Movie = require(&quot;./Movie&quot;);
var movieFinder = require(&quot;./movieFinder&quot;);
var movieLister = require(&quot;./movieLister&quot;);

movieFinder.add(Movie(&quot;Terminator&quot;, &quot;James Cameron&quot;));
movieFinder.add(Movie(&quot;Blade Runner&quot;, &quot;Ridley Scott&quot;));
movieFinder.add(Movie(&quot;Titanic&quot;, &quot;James Cameron&quot;));

var movies = movieLister.moviesDirectedBy(&quot;James Cameron&quot;);

for (var i = 0; i &lt; movies.length; i++) {
    console.log(movies[i].toString());
}
</pre>
<p>För att allt det här ska fungera behöver man naturligtvis en implementation av CommonJS Modules. På serversidan implementerar exempelvis <a target="_blank" href="http://nodejs.org/">Node.js</a> specifikationen. Om man skriver kod som ska köras i browsern kan man bland annat välja på <a href="https://github.com/linkedin/inject">inject</a> och <a href="http://requirejs.org/">require.js</a>. </p>

	Tags: <a href="http://cygni.se/taggar/commonjs/" title="commonjs" rel="tag">commonjs</a>, <a href="http://cygni.se/taggar/javascript/" title="javascript" rel="tag">javascript</a>, <a href="http://cygni.se/taggar/nodejs/" title="nodejs" rel="tag">nodejs</a><br />
]]></content:encoded>
			<wfw:commentRss>http://cygni.se/2012/03/26/moduler-i-javascript-med-commonjs/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Synkronisering av multipla Google Calendars med iPhone</title>
		<link>http://cygni.se/2012/01/24/synkronisering-av-multipla-google-calendars-med-iphone/</link>
		<comments>http://cygni.se/2012/01/24/synkronisering-av-multipla-google-calendars-med-iphone/#comments</comments>
		<pubDate>Tue, 24 Jan 2012 07:19:05 +0000</pubDate>
		<dc:creator>Nathalie Sandström</dc:creator>
				<category><![CDATA[Stacktrace]]></category>
		<category><![CDATA[cygni]]></category>
		<category><![CDATA[e-post]]></category>
		<category><![CDATA[exchange]]></category>
		<category><![CDATA[iphone]]></category>
		<category><![CDATA[microsoft]]></category>

		<guid isPermaLink="false">http://cygni.se/?p=3598</guid>
		<description><![CDATA[På Cygni använder vi Google Apps för en stor del av all kommunikation: e-post, kalendrar, wiki, kontakter o.s.v. vilket fungerar grymt. Kalenderbiten är en viktig del och personligen har jag ett tiotal olika kalendrar &#8211; egna som andras, privata som arbetsrelaterade &#8211; kopplade till mitt konto. I kombination med detta kör jag iPhone, både privat ...]]></description>
			<content:encoded><![CDATA[<p>På Cygni använder vi Google Apps för en stor del av all kommunikation: e-post, kalendrar, wiki, kontakter o.s.v. vilket fungerar grymt. Kalenderbiten är en viktig del och personligen har jag ett tiotal olika kalendrar &#8211; egna som andras, privata som arbetsrelaterade &#8211; kopplade till mitt konto. I kombination med detta kör jag iPhone, både privat och på jobbet, och ser det som en nödvändighet att kunna nå och editera mina kalendrar från den enheten.</p>
<p>Det finns redan mängder med tutorials över hur man sätter upp Google-konton på sin iPhone men jag har upplevt det aningen problematiskt att synka multipla Google-kalendrar och tänker mig att detta inlägg får fungera som en steg för steg-guide över hur jag fick till synkningen. Jag har en iPhone 3GS med iOS 5 och använder mig av <a href="http://www.google.se/mobile/sync/">Google Sync</a> för synkronisering.</p>
<p>Har du inte redan satt upp ett Google-konto på din iPhone följer du dessa steg:</p>
<ol>
<li>Under inställningsmenyn på din iPhone väljer du<strong> E-post, kontakter, kalendrar</strong></li>
<li><strong>Lägg till konto</strong></li>
<li>Välj att skapa ett <strong>Microsoft Exchange</strong>-konto (vilket är det protokoll Google Sync använder vid synkronisering till iPhone)</li>
</ol>
<p><a href="http://cygni.se/2012/01/24/synkronisering-av-multipla-google-calendars-med-iphone/gallery1-5/" rel="attachment wp-att-3636"><img src="http://cygni.se/wp-uploads/2011/10/gallery14.png" alt="Add Microsoft Exchange account" width="550" height="255" class="alignnone size-full wp-image-3636" /></a></p>
<ol start="4">
<li>Under <strong>E-post</strong> fyller du i din fullständiga e-postadress</li>
<li>Lämna <strong>domän</strong>fältet tomt</li>
<li>Fyll i din fullständiga e-postadress under <strong>Användarnamn</strong></li>
<li>Skriv in <strong>lösenordet</strong> för ditt Google-konto</li>
<li>Klicka på <strong>Nästa</strong></li>
<li>När fältet <strong>Server</strong> poppar upp fyller du i <em>m.google.com</em></li>
<li>Klicka på <strong>Nästa</strong></li>
<li>Välj vad du vill synka (denna guide kräver att du åtminstone väljer att synka kalendrar)</li>
</ol>
<p><a href="http://cygni.se/2012/01/24/synkronisering-av-multipla-google-calendars-med-iphone/gallery2/" rel="attachment wp-att-3637"><img src="http://cygni.se/wp-uploads/2011/10/gallery2.png" alt="Account information" width="550" height="255" class="alignnone size-full wp-image-3637" /></a></p>
<p>Setup av synkroniseringen är nu klar och beroende på vad du i steg 11 valde att synka kommer det nu att pushas ut information till din iPhone.</p>
<p>Med Google Sync kan du synka upp till 25 kalendrar på din iPhone vilket man enkelt ska kunna sätta upp genom att surfa in på <a href="http://m.google.com/sync">http://m.google.com/sync</a> och logga in på sitt konto. Här stötte jag dock på problem. Sidan talade om för mig att Google Sync tyvärr inte kunde stödja min enhet eftersom jag var tvungen att ha iOS 3 eller senare &#8211; något som jag uppenbarligen hade då jag precis uppdaterat till iOS 5.</p>
<p><a href="http://cygni.se/2012/01/24/synkronisering-av-multipla-google-calendars-med-iphone/error/" rel="attachment wp-att-3638"><img src="http://cygni.se/wp-uploads/2011/10/error.png" alt="" width="260" height="400" class="alignnone size-full wp-image-3638" /></a></p>
<p>Efter en tids undersökning kunde jag konstatera att detta var en bugg fler användare upplevt och en konsekvens av att Google Sync befinner sig i ett beta-stadie. Sajten kräver att sidan presenteras på engelska och det du behöver göra för att komma runt problemet är att byta språk från svenska till just engelska enligt nedan steg:</p>
<ol start="12">
<li>Med din iPhone, surfa in på <a href="http://m.google.com/sync">http://m.google.com/sync</a></li>
<li>För att ändra språk klickar du på länken <strong>Byt språk</strong> (jag valde English (UK))</li>
<li>Sidan laddas om och du har nu möjlighet att logga in. Gör detta genom att klicka på <strong>Sign in with your Google Account</strong></li>
<li>Du möts nu av de enheter du har satt upp ditt Google-konto på och genom att klicka dig in på de olika enheterna kan du välja exakt vilka kalendrar du vill synka</li>
</ol>
<p><a href="http://cygni.se/2012/01/24/synkronisering-av-multipla-google-calendars-med-iphone/gallery3/" rel="attachment wp-att-3639"><img src="http://cygni.se/wp-uploads/2011/10/gallery3.png" alt="Sync devices" width="550" height="410" class="alignnone size-full wp-image-3639" /></a></p>
<ol start="16">
<li>Efter att ha valt vilka kalendrar du vill synka och klickat på <strong>Save</strong> är du klar</li>
</ol>
<p>När du nu lägger till, editerar eller tar bort händelser i dina kalendrar kommer dessa speglas på alla enheter du synkat enligt ovan steg &#8211; detta gäller självfallet oberoende av om du gör förändringarna i kalendern på din iPhone eller i webbgränssnittet på din dator.</p>
<p><a href="http://cygni.se/2012/01/24/synkronisering-av-multipla-google-calendars-med-iphone/gallery4/" rel="attachment wp-att-3640"><img src="http://cygni.se/wp-uploads/2011/10/gallery4.png" alt="Devices synced" width="550" height="300" class="alignnone size-full wp-image-3640" /></a></p>

	Tags: <a href="http://cygni.se/taggar/cygni/" title="cygni" rel="tag">cygni</a>, <a href="http://cygni.se/taggar/e-post/" title="e-post" rel="tag">e-post</a>, <a href="http://cygni.se/taggar/exchange/" title="exchange" rel="tag">exchange</a>, <a href="http://cygni.se/taggar/iphone/" title="iphone" rel="tag">iphone</a>, <a href="http://cygni.se/taggar/microsoft/" title="microsoft" rel="tag">microsoft</a><br />
]]></content:encoded>
			<wfw:commentRss>http://cygni.se/2012/01/24/synkronisering-av-multipla-google-calendars-med-iphone/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Mockning &#8211; @InjectMocks med Mockito</title>
		<link>http://cygni.se/2012/01/11/mockning-injectmocks-med-mockito/</link>
		<comments>http://cygni.se/2012/01/11/mockning-injectmocks-med-mockito/#comments</comments>
		<pubDate>Wed, 11 Jan 2012 16:23:55 +0000</pubDate>
		<dc:creator>Leo Wentzel</dc:creator>
				<category><![CDATA[Stacktrace]]></category>
		<category><![CDATA[di]]></category>
		<category><![CDATA[ioc]]></category>
		<category><![CDATA[java]]></category>
		<category><![CDATA[java ee]]></category>
		<category><![CDATA[junit]]></category>
		<category><![CDATA[mock objects]]></category>
		<category><![CDATA[mockito]]></category>
		<category><![CDATA[spring]]></category>
		<category><![CDATA[tdd]]></category>

		<guid isPermaLink="false">http://cygni.se/?p=3848</guid>
		<description><![CDATA[När ett test skrivs för en klass som har beroenden till en datakälla, en extern service eller bara en annan klass är mockning ofta väldigt användbart. Ibland kan detta leda till att produktionskod anpassas för att det ska gå att skriva dessa tester. Nedan är exempel på ett test som testar en service som använder ...]]></description>
			<content:encoded><![CDATA[<p>När ett test skrivs för en klass som har beroenden till en datakälla, en extern service eller bara en annan klass är mockning ofta väldigt användbart. Ibland kan detta leda till att produktionskod anpassas för att det ska gå att skriva dessa tester. Nedan är exempel på ett test som testar en service som använder en entity manager.</p>
<pre class="brush: java; title: ;">
package se.cygni.blog;

import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;

import javax.persistence.EntityManager;

import org.junit.Before;
import org.junit.Test;

public class BlogServiceTest {

    private BlogService service;
    private EntityManager entityManager;

    @Before
    public void setup() {
        entityManager = mock(EntityManager.class);
        service = new BlogService(entityManager);
    }

    @Test
    public void addEntry() {
        Entry entry = new Entry(&quot;title&quot;, &quot;text&quot;);

        service.addEntry(entry);

        verify(entityManager).persist(entry);
    }

}
</pre>
<p>Testet i exemplet är relativt enkelt och verifierar endast att <em>persist</em> anropas i <em>addEntry</em> och ger oss  följande kod för ett Spring-baserat projekt:</p>
<pre class="brush: java; title: ;">
package se.cygni.blog;

import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;

import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

@Service
public class BlogService {

    @PersistenceContext
    private EntityManager entityManager;

    public BlogService() {
    }

    protected BlogService(EntityManager entityManager) {
        this.entityManager = entityManager;
    }

    @Transactional
    public void addEntry(Entry entry) {
        entityManager.persist(entry);
    }

}
</pre>
<p>För att kunna använda en mockad <em>entityManager</em> har vi lagt till en konstruktor som tar en <em>EntityManager</em> som <em>BlogService</em> sedan kan använda. Använder vi dessutom <em>&#8221;field injection&#8221;</em> är vi tvugna att lägga till en no-args-konstruktor. Alternativt hade vi kunnat lägga till en setter istället.</p>
<pre class="brush: java; title: ;">
    protected void setEntityManager(EntityManager entityManager) {
        this.entityManager = entityManager;
    }
</pre>
<p>Det är väl antagligen inte så illa att behöva lägga till konstruktorer alternativt setters även om det blir värre när en klass har flera beroenden. Däremot känns det ju lite onödigt när både Spring och Java EE numera stödjer <em>field injection</em>. Det går ju att köra enhetstesterna med till exempel Spring och låta Spring injicera alla beroenden. Detta anses dock inte helt lämpligt för enhetstester utan lämpar sig bättre för integrationstester. Istället kan <a href="http://code.google.com/p/mockito/">Mockito</a> ta hand om injicering, genom att köra testerna med <em>MockitoJUnitRunner</em> och använda annotationerna <em>@Mock</em> och <em><a href="http://docs.mockito.googlecode.com/hg/latest/org/mockito/InjectMocks.html">@InjectMocks</a></em>. Mockito fungerar då i princip som en enkel IOC-container och några extra konstruktorer eller setters behövs inte. </p>
<pre class="brush: java; title: ;">
package se.cygni.blog;

import static org.mockito.Mockito.verify;

import javax.persistence.EntityManager;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.runners.MockitoJUnitRunner;

@RunWith(MockitoJUnitRunner.class)
public class BlogServiceTest {

    @Mock
    private EntityManager entityManager;

    @InjectMocks
    private BlogService service = new BlogService();

    @Test
    public void addEntry() {
        Entry entry = new Entry(&quot;title&quot;, &quot;text&quot;);

        service.addEntry(entry);

        verify(entityManager).persist(entry);
    }
}
</pre>

	Tags: <a href="http://cygni.se/taggar/di/" title="di" rel="tag">di</a>, <a href="http://cygni.se/taggar/ioc/" title="ioc" rel="tag">ioc</a>, <a href="http://cygni.se/taggar/java/" title="java" rel="tag">java</a>, <a href="http://cygni.se/taggar/java-ee/" title="java ee" rel="tag">java ee</a>, <a href="http://cygni.se/taggar/junit/" title="junit" rel="tag">junit</a>, <a href="http://cygni.se/taggar/mock-objects/" title="mock objects" rel="tag">mock objects</a>, <a href="http://cygni.se/taggar/mockito/" title="mockito" rel="tag">mockito</a>, <a href="http://cygni.se/taggar/spring/" title="spring" rel="tag">spring</a>, <a href="http://cygni.se/taggar/tdd/" title="tdd" rel="tag">tdd</a><br />
]]></content:encoded>
			<wfw:commentRss>http://cygni.se/2012/01/11/mockning-injectmocks-med-mockito/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Java EE 6 med Spring MVC</title>
		<link>http://cygni.se/2011/12/19/java-ee-6-med-spring-mvc/</link>
		<comments>http://cygni.se/2011/12/19/java-ee-6-med-spring-mvc/#comments</comments>
		<pubDate>Mon, 19 Dec 2011 08:13:19 +0000</pubDate>
		<dc:creator>Leo Wentzel</dc:creator>
				<category><![CDATA[Stacktrace]]></category>
		<category><![CDATA[java]]></category>
		<category><![CDATA[java ee]]></category>
		<category><![CDATA[java ee 6]]></category>
		<category><![CDATA[spring]]></category>
		<category><![CDATA[spring mvc]]></category>

		<guid isPermaLink="false">http://cygni.se/?p=3784</guid>
		<description><![CDATA[Nyligen läste jag ett intressant blogginlägg där Spring jämfördes med Java EE 6. Författaren drar slutsatsen att det numera är minst lika enkelt att utveckla en applikation för Java EE-plattformen som för Spring. Då Spring, Spring MVC inkluderat, är väldigt populärt blev jag nyfiken på hur detta kan integreras med Java EE för att lättare ...]]></description>
			<content:encoded><![CDATA[<p>Nyligen läste jag ett intressant <a href="http://www.javacodegeeks.com/2011/11/from-spring-to-java-ee-6.html" title="Bloggartikel om Java EE 6" target="_blank">blogginlägg</a> där <a href="http://www.springsource.org/" title="Spring" target="_blank">Spring</a> jämfördes med Java EE 6. Författaren drar slutsatsen att det numera är minst lika enkelt att utveckla en applikation för Java EE-plattformen som för Spring. Då Spring, Spring MVC inkluderat, är väldigt populärt blev jag nyfiken på hur detta kan integreras med Java EE för att lättare dra nytta av allt som en Java EE-container kan erbjuda. Det visade sig att detta var förbluffande enkelt, till exempel går det utan ytterligare Spring-konfiguration direkt injicera en <em>Session Bean</em> i en Spring-controller.</p>
<pre class="brush: java; title: ;">
@Controller
public class MyController {

    @EJB(mappedName=&quot;java:module/MyService&quot;)
    private MyService myService;

    @RequestMapping(value = &quot;/&quot;, method = RequestMethod.GET)
    public String home(Model model) {
        model.addAttribute(&quot;message&quot;, myService.getMessage());
        return &quot;home&quot;;
    }
}
</pre>
<p>Nyckeln till att injektionen med <em>@EJB</em>-annotation fungerar, i exemplet ovan, är att <em>mappedName</em> används. Spring utför då en JNDI-lookup på det angivna JNDI-namnet. Eftersom JNDI har standardiserats i Java EE 6 är dessutom namnen portabla mellan applikationsservrar. Stödet för Java EE 6 kommer säkerligen förbättras i framtida versioner av Spring så det finns bra defaults för ejb-lookups med JNDI.</p>
<p>En annan spännande detalj med detta exempel är att <em>MyService</em> inte behöver vara ett interface eftersom Java EE 6 inte kräver detta för lokala session beans. Dessutom kan session beans paketeras tillsammans med resten av webbapplikationen i war-arkivet. D.v.s. det behövs ingen ejb-jar och inget EAR-arkiv. </p>
<p>Läs hela artikeln på <a href="http://www.javacodegeeks.com/2011/11/from-spring-to-java-ee-6.html" target="_blank" title="Java Code Geeks">Java Code Geeks</a>.</p>

	Tags: <a href="http://cygni.se/taggar/java/" title="java" rel="tag">java</a>, <a href="http://cygni.se/taggar/java-ee/" title="java ee" rel="tag">java ee</a>, <a href="http://cygni.se/taggar/java-ee-6/" title="java ee 6" rel="tag">java ee 6</a>, <a href="http://cygni.se/taggar/spring/" title="spring" rel="tag">spring</a>, <a href="http://cygni.se/taggar/spring-mvc/" title="spring mvc" rel="tag">spring mvc</a><br />
]]></content:encoded>
			<wfw:commentRss>http://cygni.se/2011/12/19/java-ee-6-med-spring-mvc/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Best of Eclipse &#8211; Godbitar, kortkommandon mm</title>
		<link>http://cygni.se/2011/12/15/best-of-eclipse-godbitar-kortkommandon-mm/</link>
		<comments>http://cygni.se/2011/12/15/best-of-eclipse-godbitar-kortkommandon-mm/#comments</comments>
		<pubDate>Thu, 15 Dec 2011 09:25:07 +0000</pubDate>
		<dc:creator>Tommy Wassgren</dc:creator>
				<category><![CDATA[Stacktrace]]></category>
		<category><![CDATA[artiklar]]></category>
		<category><![CDATA[eclipse]]></category>
		<category><![CDATA[stacktrace]]></category>
		<category><![CDATA[tips]]></category>

		<guid isPermaLink="false">http://cygni.se/?p=3644</guid>
		<description><![CDATA[Det finns mängder av artiklar här på Stacktrace som handlar om Eclipse. Jag tänkte samla ihop några godbitar som fortfarande känns relevanta. Roberts inlägg om kortkommandon och handgrepp är alltid högaktuellt. Inlägget visar bland annat på smarta kommandon för navigering och refactoring. Save Actions är ett ovärderligt verktyg om du vill hålla ordning och reda ...]]></description>
			<content:encoded><![CDATA[<p>Det finns mängder av artiklar här på Stacktrace som handlar om Eclipse. Jag tänkte samla ihop några godbitar som fortfarande känns relevanta.</p>
<ul>
<li>Roberts <a href="http://cygni.se/2007/11/27/eclipse-tips-och-tricks/" title="Eclipse Tips och Tricks">inlägg om kortkommandon och handgrepp</a> är alltid högaktuellt. Inlägget visar bland annat på smarta kommandon för navigering och refactoring.</li>
<li><a href="http://cygni.se/2009/10/07/save-actions-i-eclipse/" title="Eclipse Save Actions">Save Actions</a> är ett ovärderligt verktyg om du vill hålla ordning och reda i koden.</li>
<li><a href="http://cygni.se/2007/12/04/breakpoints-i-eclipse/" title="Conditional Breakpoints">Conditional Breakpoints och Exception Breakpoints</a> kan vara välbehövligt i vissa debugsituationer.</li>
</ul>
<p>Kolla även in en rad tips på olika <a href="http://cygni.se/?s=eclipse" title="Eclipse">smarta plugins, hur man remote-debuggar osv</a>.</p>

	Tags: <a href="http://cygni.se/taggar/artiklar/" title="artiklar" rel="tag">artiklar</a>, <a href="http://cygni.se/taggar/eclipse/" title="eclipse" rel="tag">eclipse</a>, <a href="http://cygni.se/taggar/stacktrace-2/" title="stacktrace" rel="tag">stacktrace</a>, <a href="http://cygni.se/taggar/tips/" title="tips" rel="tag">tips</a><br />
]]></content:encoded>
			<wfw:commentRss>http://cygni.se/2011/12/15/best-of-eclipse-godbitar-kortkommandon-mm/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

