Wednesday, July 17, 2013

Why you should love KDE SC

This post contains a list of tools, which I think, make KDE SC the most advanced UI/SC I know:

Flexibilty
KDE is total flexible. You can nearly customize every aspect of the desktop, how you need it.

Klipper
Klipper is a easy to use clipboard. You can switch between the things you have copied very fast. This tool is copy&paste at its best.

KRunner
This tool is amazing. Just press 'ALT+F2' and you can do everything. You can launch your apps, switch between activities or start a conversation with an contact of your adressbook.

Activities
Activities are very useful. You can create an Activity for each "real life activity". Each Activity has its own virtual workspaces, plasmoids, wallpaper and startup apps. For example you can have an Activity "Work" with the apps you need at work and an Activity "at home" with the apps you love to use at home. Of course you can pause Activities, so they don't use ressources of your system.

Plasma Dashboard/Plasmoids
There is no need to minimize your apps, so that you can interact with your desktop or plasmoids (widgets on your desktop). Just launch the plasma dashboard.

Akonadi
"One backend to rule them all". Akonadi stores your pim data (eg mail, calendar, contacts, ...) from different sources (eg Facebook, Google, ...). Your apps can use this data in different ways (plasmoids, mailclient,...). For me, it is very important that it syncs with Google Tasks!

One plattform, many beautiful UIs
You can use KDE on different form factors of devices. KDE gives you always a look and feel that fits the fom factor.

Dolphin
Very fast and also powerful file manager. Of course Dolphin is very flexible (you can add a terminal widget to the programm view ;-) )

Nepomuk
Thanks to Nepomuk, you do not search for something, you find it ;-). It stores ratings, tags and other things which you have linked to your files, mails, music and so on. So you can rate an music title with Dolphin and Amarok (music application) can youse this rating for automatic playlist generation.

Screenshot from my configuration
 

Monday, December 03, 2012

Erster Eintrag mit Blogilo

Ich habe Blogilo noch eine Chance gegeben. Dieses mal konnte das Tool seine Chance nutzen ;-). Als ich das Teil vor ca einem halben Jahr das erste mal installiert habe, wollte es sich nicht mit Blogspot verbinden. Jetzt läuft plötzlich alles so wies sein soll :-).

=-=-=-=-=
Powered by Blogilo

=-=-=-=-=
Powered by Blogilo

Friday, February 10, 2012

CDI and I

In diesem Post werden ich meine ersten Erfahrungen mit CDI festhalten. Und diese somit den Lesern meines Blogs weitergeben (falls es Leser meines Blogs gibt ;-) ).

1) Meine Entwicklungsumgebung
Als IDE verwende ich Eclipse Indigo mit dem Glassfish v3.0.1 Plugin (und somit Glassfish als AppServer). Anfänglich wollte ich Netbeans verwenden, ich komme damit aber einfach nicht mehr zurecht bzw. gefällt mir Eclipse besser (vor ein paar Jahren wollte ich von Eclipse nix wissen, irgendwie hat sich das nun geändert). PostgreSQL ist die DB meiner Wahl. Um Applikationen auch übers Internet zur Verfügung stellen zu können hab ich mich bei Jelastic registriert.

2) Grundlagen
Beans (für den CDI Container ist so ziemlich alles was injiziert werden kann eine Bean) die vom Container verwaltet werden, müssen alle lokal deployed sein. Weiters muss eine Datei beans.xml (diese kann komplett leer sein) im META-INF bei JAR-Files vorhanden sein bzw. im WEB-INF bei Webprojekten, falls das Projekt vom AppServer nach CDI Managed Beans durchsucht werden soll.
Um eine Bean zu einer CDI Managed Bean zu machen, muss sie mit der Annotation @Named versehen. Mit der Annotation @Inject können dann alle Objekte die vom Container verwaltet werden in ein anderes Objekt injiziert werden.
CDI Managed Beans "leben" in einem eigenen Context, der vom Entwickler festgelegt werden kann. Beans leben solange, wie der Context in dem sie sich befinden, das zulässt. Der Context in dem sich eine Bean befindet wird mit so genannnten Scopes per Annotation angegeben (falls kein Scope angegeben wird, befindet sich die Bean im Dependent Scope, dh die Bean ist vom Scope der Bean in die sie injiziert wird abhängig). Folgende Scopes kennt CDI (nicht zu verwechseln mit den Scopes von JSF!):
  - RequestScoped
  - ConversationScoped
  - SessionScoped
  - ApplicationScoped

Ich denke die Namen erklären bereits wie lange eine Bean lebt. Eine Besonderheit ist der ConversationScope, bei diesem Scope kann der Entwickler im Programmcode angeben wie lange eine Bean lebt (die aktuelle Conversation kann in die Bean injiziert werden, mit den Methoden begin und end kann Einfluss auf die Lebzeit des Scope genommen werden). Somit ist es zB auch möglich unterschiedliche Conversations für unterschiedliche Browsertabs anzulegen. Standardmäßig hat der ConversationScope die gleiche Lebensdauer wie ein RequestScope.

CDI ist nicht transaktionssicher, dazu werden immer noch EJBs benötigt. Diese können aber auch mit @Named annotiert und an einen Scope gebunden werden.

JPA Entities können nicht vom CDI Container verwaltet werden.

3) Wozu CDI?
CDI verbindet die Darstellung von Daten (JSF) mit der Businesslogik und deren LifeCycle nahtlos. Dank der verschiedenen Scopes befindet sich immer nur wirklich das was benötigt wird in der Session, somit wird diese Schlank gehalten.
Weiters bietet CDI typsichere Injection und dennoch eine lose Kopplung der einzelnen Programmmodule.
Das Eventsystem von CDI ist nur ein weiteres Beispiel wie elegant CDI typsichere Injection und loose Kopplung zur Verfügung stellt.

4) Was halte ich davon?
Man kann es wahrscheinlich zwischen den Zeilen lesen, das ich begeistert bin. Noch nie war es mit JavaEE möglich so schnell bzw mit so einer Leichtigkeit an sein Ziel zu kommen. Die Tage des "schwergewichtigen" J2EE sind endlich vorbei.
Der König ist tot, lang lebe der König ;-)

Folgender Post gibt Aufschluss über die verschiedenen Beantypen:

http://www.andygibson.net/blog/article/comparing-jsf-beans-cdi-beans-and-ejbs/

Labels:

Tuesday, February 07, 2012

Testeintrag

Nur ein Testeintrag, will wissen was das verknüpfen des Blogs mit G+ für Auswirkungen hat ;-)

Sunday, November 13, 2011

Kopsox Application Services

Die "KopsoxApplicationServices" stellen verschiedene Services für Java-Applikationen (Java SE) zur Verfügung. Dazu zählen:
  • Messaging
  • EJB-Lookup (EJB >= 3.1!)
  • Klassen für Security
  • Session-Handling
Alle Services sind sehr simple gehalten!

In diesem Post gehe ich auf das Messaging-System näher ein. Zentrale Komponente ist die Klasse:

SimpleMessageService

Bei dieser Klasse können Komponenten registriert werden, die dann vom Message-Service benachrichtig werden, sobald Messages verschickt werden. Eine Kompemente muss das Interface "MessageConsumer" implementieren oder von der abstrakten Klasse "AbstractMessageConsumer" erben, sodass sie beim "SimpleMessageService" registriert werden kann.

Jeder Klasse die von "AbstractMessageConsumer" erbt, können Filter zugeordnet werden (über den Konstruktor oder mit der Annotation "@MessageFilters"). Mit diesen Filtern können Messages ausgewählt werden, die dann bearbeitet werden sollen. Filter müssen das Interface "MessageFilter" implementieren.

Das "SimpleMessageSerive" stellt 2 Methoden zum verschicken von Messages zur Verfügung (meiner Meinung nach sind die Methoden selbsterklärend):
  1. sendMessageToAllConsumers
  2. sendMessageToConsumer
Die Messages werden von diesen beiden Methoden asynchron verschickt, dh jede Message wird in einem eigenen Thread abgehandelt.

Die folgende Test-Klasse zeigt die Verwendung des Services:

/**
 * @author Konrad Renner
 *
 */
public class AbstractMessageConsumerTest {
  
  protected static final String CONSUMER_NAME = "TestMessageConsumer";
  
  TestMessageConsumer testConsumer;
  
  @Before
  public void setUp() {
    testConsumer = new TestMessageConsumer();
    
    Assert.assertTrue(SimpleMessageService.registerConsumer(CONSUMER_NAME, testConsumer));
  }

  @Test
  public void testMessageSendingAndReceiving() throws Exception {
    SimpleMessage messageOne = new StandardMessage("messageOne",this);
    SimpleMessage messageHello = new StandardMessage("Hello",this);
    SimpleMessage messageConsumer = new StandardMessage("Hello",testConsumer);
    
    SimpleMessageService.sendMessageToAllConsumers(messageOne);
    SimpleMessageService.sendMessageToAllConsumers(messageHello);
    SimpleMessageService.sendMessageToAllConsumers(messageConsumer);
    
    Assert.assertTrue(SimpleMessageService.sendMessageToConsumer(CONSUMER_NAME,messageHello));
    Assert.assertFalse(SimpleMessageService.sendMessageToConsumer("test",messageHello));
    
    Thread.sleep(1000);
    
    Assert.assertEquals(2,this.testConsumer.receivedMessageCount);
  }
  
  @After
  public void tearTown() {
    Assert.assertTrue(SimpleMessageService.unregisterConsumer(CONSUMER_NAME));
  }
  
  
  @MessageFilters(filters = TestMessageFilter.class)
  private class TestMessageConsumer extends AbstractMessageConsumer{

    private String name = "TestMessageConsumer";
    protected int receivedMessageCount;
    
    TestMessageConsumer(){
      super();
      receivedMessageCount = 0;
    }
    
    @Override
    public void retrieveMessage(SimpleMessage message) {
      receivedMessageCount++;
      
      Assert.assertEquals("Hello", message.getText());
      Assert.assertNotSame(this, message.getSender());
    }

    

    @Override
    public int hashCode() {
      final int prime = 31;
      int result = 1;
      result = prime * result + getOuterType().hashCode();
      result = prime * result + ((name == null) ? 0 : name.hashCode());
      return result;
    }

    @Override
    public boolean equals(Object obj) {
      if (this == obj)
        return true;
      if (obj == null)
        return false;
      if (getClass() != obj.getClass())
        return false;
      TestMessageConsumer other = (TestMessageConsumer) obj;
      if (!getOuterType().equals(other.getOuterType()))
        return false;
      if (name == null) {
        if (other.name != null)
          return false;
      } else if (!name.equals(other.name))
        return false;
      return true;
      
    }

    private AbstractMessageConsumerTest getOuterType() {
      return AbstractMessageConsumerTest.this;
    }

    @Override
    public String toString() {
      return "TestMessageConsumer [name=" + name + "]";
    }
    
  }
  
  public static class TestMessageFilter implements MessageFilter{

    
    @Override
    public boolean isMessageServiceable(MessageConsumer consumer, SimpleMessage message) {
      return "Hello".equalsIgnoreCase(message.getText());
    }
    
  }
  
  
}


Labels:

Thursday, November 10, 2011

Vielleicht

Werde ich wieder öfters Beiträge schreiben. Dann kann ich in 4 Jahren wieder über mich lachen ;-)

Lang ists her

Lang ists her, das ich einen Post erstellt habe. Ist schon lustig, wenn man sich 4 Jahre alte Posts durchschaut :-D

Thursday, March 08, 2007

Ist Vista einen Umstieg wert?

Vista ist vor allem in Sachen Sicherheit XP überlegen, die Oberfläche wirkt auch besser und eleganter. Der "Wow"-Effekt kommt für Personen die eine 3D-Oberfläche zum ersten mal sehen sicher nicht zu kurz. Jedoch:
Ist das neu? Definitiv nicht! OSX und sämtlich GNU/Linux Distributionen beherrschen diese Effekte schon lange. Noch dazu sind die Systeme noch immer sicherer. Außerdem muss man sich nicht zwingend einen neuen PC kaufen um das System stabil zum laufen zu bekommen.
Umsteigen lohnt nicht. Prinzipiell hat sich bei Windows bewährt: Erst 1 Jahr nach erscheinen zulegen. Denn dann gibts bereits Service Packs und die benötigt man in der Regel.