суботу, 27 листопада 2010 р.

магія XSLT

збирати все в xml - це добре. далі з цим xml можна робити багато цікавого й корисного, наприклад форматувати для виводу користувачу, більше того - можна створювати xhtml з різними контролами
Для самого простого прикладу візьмемо наступний XML:
<msgs>
 <error>Login or password is wrong</error>
 <info>Cookies is disabled</info>
</msgs>

І спробуємо застосувати до нього такий XSLT:

<?xml version="1.0" encoding="ISO-8859-1"?>
<!-- Edited by XMLSpy® -->
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

<xsl:template match="/">
<xsl:for-each select='msgs/error'>
<div style='color: red'>
<xsl:value-of select='.'/>
      <xsl:for-each select="button">
<xsl:element name="input">
 <xsl:attribute name="type">button</xsl:attribute>
 <xsl:if test="@label">
   <xsl:attribute name="name"><xsl:value-of select="@label"/></xsl:attribute>
 </xsl:if>
 <xsl:attribute name="value"><xsl:value-of select="@val"/></xsl:attribute>
 <xsl:attribute name="id"><xsl:value-of select="@id"/></xsl:attribute>
 <xsl:attribute name="onclick"><xsl:value-of select="@onclick"/></xsl:attribute>
</xsl:element>
</div></br>
      </xsl:for-each>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>

На виході ми отримуємо чудовий XHTML :) якщо хочете - то навіть HTML5

понеділок, 18 жовтня 2010 р.

Jamon

JAMon (Java Application Monitor) is incredible easy-to-use roll for performance measurment for your web application. It's incredible easy to start using
What you need - add a bit code to monitored places (you are going to get frequency invokes and time), and then you are completly set. Also, you can use AOP (aspect-oriented programing) to dynamicly add performance monitorin to your applciation.
In tipycal case Jamon using is:
private void f(){
 
  Monitor mon = MonitorFactory.start("packadge.className.methodName");
try
{
  ....
 }finally{
   mon.stop();
 }
}


* This source code was highlighted with Source Code Highlighter.

The time will be measured from monitor instanced till monitor stop. You available to check min/max/avg and lst execution time for each monitor. The result can be logged with log4j, or you can check it at web UI (Jamon has special war out-of-box), or you can process/show statistic yourself.

I used JBoss, so I just copied Jamon.war deployment diectory and got beautifil, useful statistic at http://host:port/jamon/jamonadmin.jsp .
Note! In this case you must to SHARE jamon-*.jar library between two applciations - put it to specefic directory for your AS

четвер, 14 жовтня 2010 р.

thrift-protobuf-compare

Чудове порівняння різних аспектів перфомансу сучасних технологій передачі даних між аплікаціями http://code.google.com/p/thrift-protobuf-compare/wiki/BenchmarkingV2

Як на мене, Google ProtoBuf показав себе якнайкраще
Один з графіків (побудований, доречі, за допомогою Google Chart Api:))

вівторок, 31 серпня 2010 р.

Reference types in Java

Окрім знайомих всім "сильних" посилань в Java доступними є "слабкі" посилання, які не гарантують того що об"єкт на який вказує мописаляння досі існує. Посилання в Java наслідуються від абстрактного
java.lang.ref.Reference
У стандартній "поставці" доступними є три типи слабких посилань: Soft, Weak, Phantom.
Давайте розглянемо їх детальніше. Строге посилання це усім звичне стандартне посилання на об"єкт:
Quote quote = new Quote();
Quote strongReference = new Quote();
маємо два посилання на один об"єкт в кучі, і це об"єкт не буде зібраний збірником сміття доти, доки досяжними є хоч одне з написаних нами посилань.
Інша ситуація з "слабкими" посиланнями.
Розглянемо детальніше SoftReference:
Quote quote = new Quote();
SoftReference softQuote = new SoftReference(new Quote());
У цьому випадку життя об"єкта гарантуєтсья лише першим "сильним" посиланням. Якщо він стає недоступним, то... то це ще не означає, що об"єкт буде зібраний GC. GC забере об"єкт в той момент, коли "він" вирішить, що пам"яті недостатньо. Тобто, файтично момент смерті об"єкту передбачити неможливо. Ця особливість корисна для організації різноманітних кешів об"єктів.
WeakReference:
Quote quote = new Quote();
WeakReference softQuote = new WeakReference(new Quote());
є корисними, коли ми хоче, щоб життя об"єкту залежило від одного сильного посилання. Щойно воно стає недоступним. як наступний запуск GC збере його.

PhantomReference:
Quote quote = new Quote();
PhantomReference softQuote = new PhantomReference(new Quote());
Найбільш слабкими посиланнями з існуючих є звісно PhantomReference, для яких PhantomReference.get() завжди повертає null. Фантомні референси символізують об"єкт для якого вже був викликаний finilaze, але він ще не зібраний GC. Їх практична складова знаходиться під сумнівом. У статті http://www.javaspecialists.co.za/archive/Issue098.html розглядаєть створення власного кастомного типу посилань та його використання.

четвер, 8 липня 2010 р.

Будуємо мурашкою

У цьому дописі акцент робиться на:
1) білді антом після успішного проходження юніт тесту
2) автоматична генерація номера білда/допис дати/тощо з подальшим доступом до цих мета-даних білда з коду

Юніт тести виглядає цілком логічним проганяти перед кожним білдом, тому в антовському build.xml цілком логічно написати щось назразок:

  1. <target name="test" depends="compile-test">
  2.    <junit failureProperty="tests.failed">
  3.    <classpath refid="classpath.libs" />
  4.    <classpath>
  5.   <pathelement path="build"/>
  6.   </classpath>
  7.     <formatter type="brief" usefile="false" />
  8.     <test name="my.own.TweetProducerTest" />
  9.    </junit>
  10. </target>
* This source code was highlighted with Source Code Highlighter.

Де compile-test таска для компілу юніт-тестів, а "зміна" tests.failed слугує якраз для відслідковування вдалого проходження тест-кейсу. Лише за умови вдалого проходження тестів таска, що збирає джар:

  1. <target name="build" depends="test" unless="tests.failed">
  2.   <antcall target="jar"/>
  3. </target>
* This source code was highlighted with Source Code Highlighter.

А ось і ця таска, описую також створення маніфесту

  1. <target name="jar" depends="compile">
  2.     <delete file="tweet.jar"/>
  3.     <property name="version.num" value="1.0"/>
  4.     <tstamp>
  5.       <format property="TODAY" pattern="yyyy-MM-dd HH:mm:ss" />
  6.   </tstamp>
  7.      <buildnumber file="build.num"/>
  8.     <manifest file="MANIFEST.MF">
  9.       <attribute name="Built-By" value="${user.name}"/>
  10.       <attribute name="Implementation-Version"
  11.            value="${version.num}-${build.number}"/>  
  12.       <attribute name="Built-Date" value="${TODAY}"/>   
  13.   </manifest>
  14.     <jar destfile="tweet.jar"
  15.       basedir="build"
  16.        includes="**/*.class"
  17.        excludes="**/*Test*.class"
  18.        manifest="MANIFEST.MF"
  19.     />
  20. </target>
* This source code was highlighted with Source Code Highlighter.
Цей код заслуговує на більш детальний розбір. Почнемо з кінця - створення джару - до нього пакуються усі класс-файли за викюченням тих, імена яких закінчуютсья на Test - це юніт-тести і вони нам не потрібні в нашій джарці.

Загадковий  посилається до відповідного файлу на файловій системі (який модифікувати/видаляти треба обережно) і забезпечує нам номер білду.

Найцікавішою частиною звісно є опис файлу маніфесту, який дозволяє нам задати наші додаткові атрибути. Імена атрибутів цілком описують їх значення... Файл маніфесту вийде приблизно таким:

Manifest-Version: 1.0
Ant-Version: Apache Ant 1.7.1
Created-By: 14.1-b02 (Sun Microsystems Inc.)
Build-By: kostya
Implementation-Version: 1.0-5
Build-Date: 2010-06-12 18:47:34

Для читання цих даних можна використати наступний код (Groovy):

Enumeration e = Thread.currentThread().getContextClassLoader().getResources("META-INF/MANIFEST.MF");
while (e.hasMoreElements()){
JarURLConnection jarConnection = (JarURLConnection)(e.nextElement().openConnection());
Manifest mf = jarConnection.getManifest();
Attributes attr = mf.getMainAttributes();
String libraryFor = attr.getValue("LibraryFor");
attr.getValue("Implementation-Version");
String version = attr.getValue("Implementation-Version");

вівторок, 22 червня 2010 р.

Ієрархічні структури в Oracle

Трапляється таке в житті, що доводеться різні ієрархічні структури збрегати до реляційних СКБД. І що ще гірше, потім їх оброблювати. Власне, залишимо механіхми мапінгу осторонь і звернемо наші погляди на те, як можна елегантно працювати з ієрархіями в Oracle (звісно, якщо вам пощастило і у вас Oracle).
Мова йде про використання своєрідного "синтаксичного цукру" start with .. connect by

Отже, якщо у вас є дерево і ви створете таблицю на зразок
create table node(
id number,
parent number,
my_data varchar2(80)
);

заповните цю таблицю даними, то пройти по ієрархії, знаючи лише батька буде дуже просто, а саме:
select lpad(' ',2*(level-1)) || my_data tree_node    from node    start with id=?   connect by prior id = parent;
тобто ідея зрозуміла. level - це псевдоколонка, яка автоматично з"являється
під час операцій над ієрархічними структурами (рахувати починаємо з 1) 
Так само просто зробити якийсь апдейт, наприклад
update node set my_data = 'Wine'
where id in (select id from node start with id=? connect by prior id = parent)
PS. мій перший допис. будьте ласкаві, не ругайте дуже сильно:)