Specyfikacja projektu:\\ ** Utworzenie schematu bazy danych przy pomocy własnego ORM Niberhate w liście mailingowej „Mailing Clear”** Motywacja: W dzisiejszych czasach podstawowym problemem społeczeństwa jest szybka możliwość przekazania informacji, które w jasny, szybki i klarowny sposób przedstawią problem o którym mówi korespondencja. Program Mailing Clear zostałby kupiony przez klientów z powodu dużego nacisku który kładzie on na przejrzystość otrzymywanych informacji, ich zbiorów i połączeń. Podstawowym powodem dla którego ludzie wybiorą nasz produkt będzie niska cena oraz wysoka jakość produktu w połączeniu z supportem w postaci aktualizacji.Jednym ze sposobów zarobienia na tym pieniędzy będzie opłata pobierana za każda licencję, oraz opłaty za support w postaci rocznego abonamentu.\\ \\ Opis istniejących rozwiązań:\\ Jednym z przykładowych istniejących już rozwiązań jest „Email Marketing Software”, który określa siebie najlepszym oprogramowaniem do wysyłania list emailowych na świecie. Oprogramowanie to umożliwia zakładanie oraz pełne zarządzanie listą mailingową. Lista ta jest dostępna z każdego komputera na świecie. Oprogramowanie jest uruchomione na serwerach firmy produkującej to oprogramowanie. Wszystkie e-maile są również wysyłane najszybciej jak się da przez serwery pocztowe producenta. Producent chwali się 12 latami doświadczenia i więcej niż 12 tysiącami klientów, co przekłada się na ponad 50 000 tysięcy lista mailingowych w ponad 100 krajach.\\ \\ Innowacyjność rozwiązania:\\ Innowacyjnością w projekcie jest sposób w jaki użytkownik może odbierać wiadomości z różnych list, do których jest zapisany. Będzie miał możliwość odbierać same tytuły wiadomości, tytuły+załącznik do wiadomości lub całe wiadomości. Umożliwi to dopasowanie otrzymywanych zbiorów wiadomości do potrzeb czytającego, pozwoli mu to zaoszczędzić czas na przeglądanie setek wiadomości.\\ \\ Funkcjonalność produktu:\\ Projekt będzie posiadał następujące funkcjonalności:\\ - Tworzenie/edycja/usuwanie list e-mailowych - Dodawanie e-maili do listy - Zarządzanie już utworzoną lista - Sklejanie dwóch list w całość - Pełna personalizacje formy i sposobu otrzymywania wiadmości - Możliwość odbierania nagłówków wiadomości z linkami do pełnych wiadomości - Możliwość odbierania pełnych wiadomości z linkami do załączników - Możliwość otrzymywania okresowych digestów zawierających: nagłówki wiadomości będące linkami do pełnych wiadomości pełne wiadomości z linkami do załączników Zadania, moduły do wykonania: - projekt bazy danych - konfiguracja i zarządzanie serwerem bazy danych - moduł persystencji obiektów - procedury Java Script - walidacja formularzy - projekt strony, CSS, HTML - przetwarzanie zapytań klientów - logika biznesowa - strona kliencka - strona zarządzania listami Promocja i reklama: Słowa kluczowe dla projektu tu: * lista mailingowa * lista dystrybucyjna * newsletter * oprogramowanie informacyjne * wysyłka wiadomości Jednym z miejsc gdzie można by reklamować oprogramowanie byłyby strony firm sprzedających hosting we wszelkiej postaci. Jest to uwarunkowane tym że oprogramowanie to jest raczej specyficznym produktem, którego nie warto reklamować na przykład na portalach społecznościowych. Jest on przeznaczony dla z góry określonej rzeszy odbiorców, zainteresowanych w szybkim i sprawnym informowaniu swoich klientów czy pracowników. **Opis wykonanego systemu ORM Niberhate**\\ \\ Specyfikacja wymagań: \\ - Mapowanie i konwersja pól należących do encji, obejmujące wszystkie podstawowe typy danych. Przykładowo: typ int z języka Java zostanie zmapowany na typ INTEGER w bazie danych. Mapowanie ma być realizowane za pomocą dostarczonych przez projekt adnotacji języka Java. - Możliwość reprezentacji wszystkich 7 (według JPA) rodzajów relacji pomiędzy tabelami w RDBMS. Przykładowo: Jeżeli encja zawiera pole będące referencją do innej encji, to w bazie danych powstanie odpowiednia relacja (Jeden-do-Jednego lub Wiele-do-Jednego). Mapowanie relacji ma być realizowane za pomocą adnotacji języka Java. - Zarządca encji (ang. Entity Manager) pozwalający na: wyszukanie encje w bazie danych, utworzenie nowej encji w bazie danych oraz zsynchronizowanie stanu encji z jej stanem w bazie danych, usunięcie encji z bazy danych, itp. - Wszystkie mapowania mają spełniać paradygmat "configuration by exception" tzn. jeżeli nie podano mapowania wprost za pomocą adnotacji, to użyte będzie mapowanie domyślne. Jeżeli użytkownik nie chce mapować pewnego pola należącego do encji, to może użyć specjalnej adnotacji zapobiegającej mapowaniu danego pola. - Parametry połączenia ze źródłem danych oraz inne dane konfiguracyjne powinny być odczytywane z pliku konfiguracyjnego. \\ \\ **Środowisko uruchomieniowe:**\\ Projekt docelowo jest przeznaczony dla środowiska w jakim został zaprojektowany i przetestowany. Odmienne wersje poszczególnych komponentów środowiska mogą powodować, że system nie będzie działał zgodnie z założeniami lub nie będzie funkcjonował w ogóle. \\ System operacyjny: Windows XP Proffesional SP3 Java: JDK 1.6 Update 18 Silnik baz danych: PostgreSQL 8.4 \\ **Pliki wchodzące w skład biblioteki:**\\ Framework Niberhate składa się z jednego pliku JAR o nazwie "niberhate.jar", zawierającego wszystkie klasy wchodzące w skład frameworka oraz z bibliotek pomocniczych, używanych przez framework, dostarczonych w folderze "lib": \\ Wszystkie te pliki należy umieścić w lokalizacji CLASSPATH swojego projektu. \\ \\ **Plik konfiguracyjny:**\\ Aby móc korzystać z frameworka Niberhate należy w folderze "META-INF" w zasobach swojego projektu umieścić plik o nazwie "niberhate.xml" zawierający poprawną konfigurację frameworka w formacie XML. Przykładowy plik konfiguracyjny: jdbc:postgresql://127.0.0.1/test postgres postgres true nh create **datasource** - zawiera informacje dotyczące źródła danych, z którym nawiązane ma zaostać połączenie. Ten element musi zawierać: * **connection-url** – URL połączenia zgodny ze standardem JDBC. * **user** – nazwa użytkownika w bazie danych * **password** – hasło użytkownika w bazie danych **properties** – Dodatkowe właściwości silnika persystencji: * **show_sq**l – parametr logiczny, określający, czy silnik persystencji ma wyświetlać generowany kod SQL. Możliwe wartości: true lub false. Domyślna wartość to false. * **schema_name** – nazwa schematu w bazie danych, na którym będzie operował silnik persystencji. Jeśli nie podano tego parametru, to przyjęty zostanie schemat publiczny (public). * **schema_action** - określa jaką czynność silnik persystencji ma wykonać na schemacie bazy danych podczas startu. Możliwe wartości to: create, oraz none \\ \\ **Użycie silnika:** \\ Rozpoczęcie działania frameworka Niberhate nie jest automatyczne. Należy wprost wywołać statyczną metodę **start()** klasy **org.niberhate.Engine**, która rozpocznie działanie silnika Niberhate. Należy wywołać tą metodę zanim zacznie się korzystać z jakichkolwiek encji oraz klasy EntityManager. \\ import org.niberhate.Engine; public class Main { public static void main(String[] args) { try { // Zainicjalizowanie silnika Niberhate Engine.start(); // Utworzenie EntityManagera EntityManager em = new EntityManager(); // Utworzenie instancji encji Customer cust = new Customer("Jan", "Iksiński"); // Utrwalenie encji em.persist(cust); // Zamknięcie EntityManagera em.close(); } catch (Exception e) { e.printStackTrace(); } } } \\ \\ **Adnotacje:**\\ * **@org.niberhate.annotation.Entity** – klasa oznaczona tą adnotacją staje się komponentem encyjnym. Dla wszystkich pól klasy wykonywane są odpowiednie mapowania i tworzony jest schemat tabeli w bazie danych. Klas musi obowiązkowo zawierać dokładnie jedno pole oznaczone adnotacją @Id pełniące rolę klucza głównego. \\ \\ * **@org.niberhate.annotation.Id** – Pole oznaczone tą adnotacją będzie pełnić rolę klucza głównego tabeli (encji) w której się znajduje. Kluczem głównym ma być dokładnie jedno pole. Niberhate nie zapewnia wsparcia dla kluczy złożonych. \\ \\ * **@org.niberhate.annotation.Column** – pozwala ręcznie skonfigurować parametry mapowania dla danego pola klasy encyjnej, takiej jak np. nazwa kolumny w tabeli skojarzonej z encją. Brak adnotacji lub nie określenie wszystkich parametrów spowoduje przyjęcie wartości domyślnych. \\ \\ * **@org.niberhate.annotation.OneToOne** – może być umieszczona jedynie przy polu będącym referencją do innej klasy encyjnej. Powoduje utworzenie relacji Jeden-Do-Jednego pomiędzy obiema klasami encji. \\ \\ * **@org.niberhate.annotation.OneToMany** – może być umieszczona jedynie przy polu będącym kolekcją, której przechowywany typ jest inną klasą encyjną. Przez kolekcję rozumiany jest interfejs java.util.Collection lub dowolny interfejs po nim dziedziczący lub dowolna klasa implementująca ten interfejs, np. Collection, List, ArrayList, LinkedList, Set, HashSet. Powoduje utworzenie relacji Jeden-Do-Wielu pomiędzy obiema klasami encji. \\ \\ * **@org.niberhate.annotation.ManyToMany** – może być umieszczona jedynie przy polu będącym kolekcją, której przechowywany typ jest inną klasą encyjną. Przez kolekcję rozumiany jest interfejs java.util.Collection lub dowolny interfejs po nim dziedziczący lub dowolna klasa implementująca ten interfejs, np. Collection, List, ArrayList, LinkedList, Set, HashSet. Powoduje utworzenie relacji Wiele-Do-Wielu pomiędzy obiema klasami encji. \\ \\ * **@org.niberhate.annotation.ManyToOne** – musi być umieszczona przy polu będącym referencją do klasy encyjnej. Powoduje utworzenie relacji Wiele-Do-Jednego pomiędzy obiema klasami encji. \\ \\ * **@org.niberhate.annotation.Transient** – pole oznaczone tą adnotacją nie będzie mapowane przez silnik persystencji. W tym przypadku pole nie może zawierać żadnych innych adnotacji z pakietu org.niberhate.annotation \\ \\ \\ \\ **Klasa encyjna** \\ \\ Nie ma znaczenia, czy pola encji są publiczne, prywatne czy chronione. Dla każdego pola (oprócz pól oznaczonych przez @Transient) wymagana jest para metod: Metoda odczytująca (Getter) oraz metoda zapisująca (Setter), ponieważ tylko dzięki nim silnik persystencji uzyskuje dostęp do pól encji. Metody muszą być zgodne z ogólnie przyjętą konwencją (przykładem może być sposób w jaki Eclipse generuje gettery i settery). \\ Klasa musi posiadać bezparametrowy konstruktor. Silnik persystencji użyje właśnie tego konstruktora do dynamicznego tworzenia instancji encji. \\ Przykładowa, poprawnie zmapowana klasa encji: \\ \\ @Entity(tableName = "CUSTOMERS") public class Customer { @Id(generationType=GenerationType.SEQUENCE, sequenceName="CUSTOMERS_SEQ") private int id; @Column(name="FISRT_NAME", length=40, nullable=false ) private String firstName; @Column(name="LAST_NAME", length=60, nullable=false) private String lastName; @OneToOne private Address address; public int getId() { return id; } public void setId(int id) { this.id = id; } public String getFirstName() { return firstName; } public void setFirstName(String firstName) { this.firstName = firstName; } public String getLastName() { return lastName; } public void setLastName(String lastName) { this.lastName = lastName; } public Address getAddress() { return address; } public void setAddress(Address address) { this.address = address; } } \\ \\ **Użyte wzorce projektowe:** * Model Dziedziny * Data Mapper * Architektura 2-warstwowa (warstwa logiki, warstwa bazy danych) * Mapowanie relacji: * Identity Field * Foreign Key Mapping * Assotiation Table Mapping * Metadata Mapping (metadanymi są adnotacje Javy) **Dynamika obiektu encji:** \\ \\ {{:pl:dydaktyka:ztb:2010:projekty:mailing_clear:dynamika.png|}}