--- /dev/null
+package com.itmill.toolkit.demo.reservation;\r
+\r
+import java.util.Date;\r
+import java.util.HashMap;\r
+import java.util.Iterator;\r
+import java.util.LinkedList;\r
+\r
+import com.itmill.toolkit.Application;\r
+import com.itmill.toolkit.data.Container;\r
+import com.itmill.toolkit.data.Item;\r
+import com.itmill.toolkit.data.Property;\r
+import com.itmill.toolkit.data.Property.ValueChangeEvent;\r
+import com.itmill.toolkit.data.Property.ValueChangeListener;\r
+import com.itmill.toolkit.ui.Button;\r
+import com.itmill.toolkit.ui.CalendarField;\r
+import com.itmill.toolkit.ui.Layout;\r
+import com.itmill.toolkit.ui.OrderedLayout;\r
+import com.itmill.toolkit.ui.Panel;\r
+import com.itmill.toolkit.ui.Select;\r
+import com.itmill.toolkit.ui.Table;\r
+import com.itmill.toolkit.ui.TextField;\r
+import com.itmill.toolkit.ui.Window;\r
+import com.itmill.toolkit.ui.Button.ClickEvent;\r
+\r
+public class ReservationApplication extends Application {\r
+\r
+ private SampleDB db;\r
+ \r
+ private Window mainWindow;\r
+\r
+ private CalendarField reservedFrom;\r
+ private CalendarField reservedTo;\r
+ private TextField description;\r
+ private Button reservationButton;\r
+ \r
+ private Integer selectedResource = null;\r
+ \r
+ public void init() {\r
+ mainWindow = new Window("Reservr");\r
+ setMainWindow(mainWindow);\r
+ setTheme("example");\r
+\r
+ db = new SampleDB(true);\r
+ db.generateResources();\r
+ db.generateDemoUser();\r
+ \r
+ ResourcePanel resourcePanel = new ResourcePanel("Resources");\r
+ resourcePanel.setResourceContainer(db.getResources(null));\r
+ mainWindow.addComponent(resourcePanel);\r
+ \r
+ Panel reservationPanel = new Panel(new OrderedLayout(OrderedLayout.ORIENTATION_HORIZONTAL));\r
+ mainWindow.addComponent(reservationPanel);\r
+ \r
+ OrderedLayout infoLayout = new OrderedLayout();\r
+ reservationPanel.addComponent(infoLayout);\r
+ description = new TextField();\r
+ description.setColumns(30);\r
+ description.setRows(5);\r
+ infoLayout.addComponent(description);\r
+ reservationButton = new Button("Make reservation",this,"makeReservation");\r
+ infoLayout.addComponent(reservationButton);\r
+\r
+ // TODO Use calendar, set following hour\r
+ Date now = new Date();\r
+ reservedFrom = new CalendarField();\r
+ reservedFrom.setMinimumDate(now);\r
+ initCalendarFieldPropertyIds(reservedFrom);\r
+ reservationPanel.addComponent(reservedFrom);\r
+ reservedTo = new CalendarField();\r
+ reservedTo.setMinimumDate(now);\r
+ initCalendarFieldPropertyIds(reservedTo);\r
+ reservationPanel.addComponent(reservedTo);\r
+ refreshReservations(null);\r
+ reservedFrom.addListener(new ValueChangeListener() {\r
+ public void valueChange(ValueChangeEvent event) {\r
+ Date fd = (Date)reservedFrom.getValue();\r
+ Date td = (Date)reservedTo.getValue();\r
+ if (fd == null) {\r
+ reservedTo.setValue(null);\r
+ reservedTo.setEnabled(false);\r
+ return;\r
+ } else {\r
+ reservedTo.setEnabled(true);\r
+ }\r
+ reservedTo.setMinimumDate(fd);\r
+ if (td == null||td.before(fd)) {\r
+ reservedTo.setValue(fd);\r
+ }\r
+ } \r
+ });\r
+ reservedFrom.setImmediate(true);\r
+ reservedFrom.setValue(now);\r
+\r
+ \r
+\r
+ mainWindow.addComponent(new Button("close",this,"close"));\r
+ Table tbl = new Table();\r
+ tbl.setContainerDataSource(db.getUsers());\r
+ mainWindow.addComponent(tbl);\r
+\r
+ }\r
+\r
+\r
+ public void makeReservation() {\r
+ Integer rid = getSelectedResourceId();\r
+ if (rid!=null) {\r
+ db.addReservation(rid.intValue(), 0, (Date)reservedFrom.getValue(), (Date)reservedTo.getValue(), (String)description.getValue());\r
+ refreshReservations(new int[] {rid.intValue()});\r
+ }\r
+ }\r
+ \r
+ private void refreshReservations(int[] resourceIds) {\r
+ Container reservations = db.getReservations(resourceIds);;\r
+ System.err.println("Got " + (reservations!=null?reservations.size():0) + " reservations");\r
+ reservedFrom.setContainerDataSource(reservations);\r
+ reservedTo.setContainerDataSource(reservations);\r
+ }\r
+ private void initCalendarFieldPropertyIds(CalendarField cal) {\r
+ cal.setItemStartPropertyId(SampleDB.Reservation.PROPERTY_ID_RESERVED_FROM);\r
+ cal.setItemEndPropertyId(SampleDB.Reservation.PROPERTY_ID_RESERVED_TO);\r
+ cal.setItemTitlePropertyId(SampleDB.Reservation.PROPERTY_ID_DESCRIPTION);\r
+ }\r
+ \r
+ private void setSelectedResourceId(Integer id) {\r
+ selectedResource = id;\r
+ if (id == null) {\r
+ reservationButton.setEnabled(false);\r
+ } else {\r
+ reservationButton.setEnabled(true);\r
+ }\r
+ }\r
+ private Integer getSelectedResourceId() {\r
+ return selectedResource;\r
+ }\r
+ \r
+ private class ResourcePanel extends Panel implements Button.ClickListener {\r
+ \r
+ private HashMap categoryLayouts = new HashMap();\r
+ private HashMap categoryResources = new HashMap();\r
+ \r
+ public ResourcePanel(String caption) {\r
+ super(caption,new OrderedLayout(OrderedLayout.ORIENTATION_HORIZONTAL));\r
+ }\r
+ \r
+ public void setResourceContainer(Container resources) {\r
+ this.removeAllComponents();\r
+ categoryLayouts.clear();\r
+ categoryResources.clear();\r
+ if (resources!=null&&resources.size()>0) {\r
+ for (Iterator it = resources.getItemIds().iterator();it.hasNext();) {\r
+ Item resource = (Item)resources.getItem(it.next());\r
+ Integer id = (Integer)resource.getItemProperty(SampleDB.Resource.PROPERTY_ID_ID).getValue();\r
+ String category = (String)resource.getItemProperty(SampleDB.Resource.PROPERTY_ID_CATEGORY).getValue();\r
+ String name = (String)resource.getItemProperty(SampleDB.Resource.PROPERTY_ID_NAME).getValue();\r
+ String description = (String)resource.getItemProperty(SampleDB.Resource.PROPERTY_ID_DESCRIPTION).getValue();\r
+ Button rButton = new Button(name,this);\r
+ rButton.setStyle("link");\r
+ rButton.setDescription(description);\r
+ rButton.setData(id);\r
+ Layout resourceLayout = (Layout)categoryLayouts.get(category);\r
+ LinkedList resourceList = (LinkedList)categoryResources.get(category);\r
+ if (resourceLayout==null) {\r
+ resourceLayout = new OrderedLayout();\r
+ this.addComponent(resourceLayout);\r
+ categoryLayouts.put(category, resourceLayout);\r
+ resourceList = new LinkedList();\r
+ categoryResources.put(category, resourceList);\r
+ Button cButton = new Button(category + " (any)",this);\r
+ cButton.setStyle("link");\r
+ cButton.setData(category);\r
+ resourceLayout.addComponent(cButton);\r
+ } \r
+ resourceLayout.addComponent(rButton);\r
+ resourceList.add(id);\r
+ }\r
+ }\r
+ }\r
+\r
+ public void buttonClick(ClickEvent event) {\r
+ Object source = event.getSource();\r
+ if (source instanceof Button) {\r
+ Object data = ((Button)source).getData();\r
+ if (data instanceof Integer) {\r
+ Integer resourceId = (Integer)data;\r
+ setSelectedResourceId(resourceId);\r
+ refreshReservations(new int[] {resourceId.intValue()});\r
+ } else {\r
+ setSelectedResourceId(null);\r
+ String category = (String)data;\r
+ LinkedList resources = (LinkedList)categoryResources.get(category);\r
+ int[] rids = new int[resources.size()];\r
+ for (int i = 0; i< rids.length;i++) {\r
+ rids[i] = ((Integer)resources.get(i)).intValue();\r
+ }\r
+ refreshReservations(rids);\r
+ }\r
+ }\r
+ \r
+ }\r
+ \r
+ }\r
+}\r
--- /dev/null
+package com.itmill.toolkit.demo.reservation;
+
+import java.sql.Connection;
+import java.sql.DriverManager;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.sql.Statement;
+import java.util.Date;
+
+import com.itmill.toolkit.data.Container;
+import com.itmill.toolkit.data.util.QueryContainer;
+
+public class SampleDB {
+ public class User {
+ public static final String TABLE = "user";
+ public static final String PROPERTY_ID_ID = "ID";
+ public static final String PROPERTY_ID_FULLNAME = "FULLNAME";
+ public static final String PROPERTY_ID_EMAIL = "EMAIL";
+ public static final String PROPERTY_ID_PASSWORD = "PASSWORD";
+ public static final String PROPERTY_ID_DELETED = "DELETED";
+ }
+
+ public class Resource {
+ public static final String TABLE = "resource";
+ public static final String PROPERTY_ID_ID = "ID";
+ public static final String PROPERTY_ID_NAME = "NAME";
+ public static final String PROPERTY_ID_DESCRIPTION = "DESCRIPTION";
+ public static final String PROPERTY_ID_LOCATIONX = "LOCATION_X";
+ public static final String PROPERTY_ID_LOCATIONY = "LOCATION_Y";
+ public static final String PROPERTY_ID_CATEGORY = "CATEGORY";
+ public static final String PROPERTY_ID_DELETED = "DELETED";
+ }
+
+ public class Reservation {
+ public static final String TABLE = "reservation";
+ public static final String PROPERTY_ID_ID = "ID";
+ public static final String PROPERTY_ID_DESCRIPTION = "DESCRIPTION";
+ public static final String PROPERTY_ID_RESOURCE_ID = "RESOURCE_ID";
+ public static final String PROPERTY_ID_RESERVED_BY_ID = "RESERVED_BY_USER_ID";
+ public static final String PROPERTY_ID_RESERVED_FROM = "RESERVED_FROM";
+ public static final String PROPERTY_ID_RESERVED_TO = "RESERVED_TO";
+ }
+
+ // TODO -> param
+ private static final String DB_URL = "jdbc:hsqldb:file:reservation.db";
+
+ private static final String CREATE_TABLE_USER = "CREATE TABLE "
+ + User.TABLE + " (" + " " + User.PROPERTY_ID_ID
+ + " INTEGER IDENTITY" + ", " + User.PROPERTY_ID_FULLNAME
+ + " VARCHAR(100) NOT NULL" + ", " + User.PROPERTY_ID_EMAIL
+ + " VARCHAR(50) NOT NULL" + ", " + User.PROPERTY_ID_PASSWORD
+ + " VARCHAR(20) NOT NULL" + ", " + User.PROPERTY_ID_DELETED
+ + " BOOLEAN DEFAULT false NOT NULL" + ", UNIQUE("
+ + User.PROPERTY_ID_FULLNAME + "), UNIQUE(" + User.PROPERTY_ID_EMAIL
+ + ") )";
+ private static final String CREATE_TABLE_RESOURCE = "CREATE TABLE "
+ + Resource.TABLE + " (" + " " + Resource.PROPERTY_ID_ID
+ + " INTEGER IDENTITY" + ", " + Resource.PROPERTY_ID_NAME
+ + " VARCHAR(30) NOT NULL" + ", " + Resource.PROPERTY_ID_DESCRIPTION
+ + " VARCHAR(100)" + ", " + Resource.PROPERTY_ID_LOCATIONX
+ + " DOUBLE" + ", " + Resource.PROPERTY_ID_LOCATIONY + " DOUBLE"
+ + ", " + Resource.PROPERTY_ID_CATEGORY + " VARCHAR(30)" + ", "
+ + Resource.PROPERTY_ID_DELETED + " BOOLEAN DEFAULT false NOT NULL"
+ + ", UNIQUE(" + Resource.PROPERTY_ID_NAME + "))";
+ private static final String CREATE_TABLE_RESERVATION = "CREATE TABLE "
+ + Reservation.TABLE + " (" + " " + Reservation.PROPERTY_ID_ID
+ + " INTEGER IDENTITY" + ", " + Reservation.PROPERTY_ID_RESOURCE_ID
+ + " INTEGER" + ", " + Reservation.PROPERTY_ID_RESERVED_BY_ID
+ + " INTEGER" + ", " + Reservation.PROPERTY_ID_RESERVED_FROM
+ + " TIMESTAMP NOT NULL" + ", "
+ + Reservation.PROPERTY_ID_RESERVED_TO + " TIMESTAMP NOT NULL"
+ + ", " + Reservation.PROPERTY_ID_DESCRIPTION + " VARCHAR(100)"
+ + ", FOREIGN KEY (" + Reservation.PROPERTY_ID_RESOURCE_ID
+ + ") REFERENCES " + Resource.TABLE + "(" + Resource.PROPERTY_ID_ID
+ + "), FOREIGN KEY (" + Reservation.PROPERTY_ID_RESERVED_BY_ID
+ + ") REFERENCES " + User.TABLE + "(" + User.PROPERTY_ID_ID + "))";
+
+ private Connection connection = null;
+
+ /**
+ * Create database.
+ */
+ public SampleDB() {
+ this(false);
+ }
+
+ public SampleDB(boolean recreate) {
+ // connect to SQL database
+ connect();
+
+ if (recreate) {
+ dropTables();
+ }
+
+ // initialize SQL database
+ createTables();
+
+ // test by executing sample JDBC query
+ testDatabase();
+ }
+
+ private void dropTables() {
+ try {
+ update("DROP TABLE " + Reservation.TABLE);
+ } catch (SQLException IGNORED) {
+ // IGNORED, assuming it was not there
+ }
+ try {
+ update("DROP TABLE " + Resource.TABLE);
+ } catch (SQLException IGNORED) {
+ // IGNORED, assuming it was not there
+ }
+ try {
+ update("DROP TABLE " + User.TABLE);
+ } catch (SQLException IGNORED) {
+ // IGNORED, assuming it was not there
+ }
+ }
+
+ /**
+ * Connect to SQL database. In this sample we use HSQLDB and an toolkit
+ * named database in implicitly created into system memory.
+ *
+ */
+ private void connect() {
+ try {
+ Class.forName("org.hsqldb.jdbcDriver").newInstance();
+ connection = DriverManager.getConnection(DB_URL);
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ /**
+ * use for SQL commands CREATE, DROP, INSERT and UPDATE
+ *
+ * @param expression
+ * @throws SQLException
+ */
+ private void update(String expression) throws SQLException {
+ Statement st = null;
+ st = connection.createStatement();
+ int i = st.executeUpdate(expression);
+ if (i == -1) {
+ System.out.println("SampleDatabase error : " + expression);
+ }
+ st.close();
+ }
+
+ /**
+ * Create test table and few rows. Issue note: using capitalized column
+ * names as HSQLDB returns column names in capitalized form with this demo.
+ *
+ */
+ private void createTables() {
+ try {
+ String stmt = null;
+ stmt = CREATE_TABLE_RESOURCE;
+ update(stmt);
+ } catch (SQLException e) {
+ if (e.toString().indexOf("Table already exists") == -1)
+ throw new RuntimeException(e);
+ }
+ try {
+ String stmt = null;
+ stmt = CREATE_TABLE_USER;
+ update(stmt);
+ } catch (SQLException e) {
+ if (e.toString().indexOf("Table already exists") == -1)
+ throw new RuntimeException(e);
+ }
+ try {
+ String stmt = null;
+ stmt = CREATE_TABLE_RESERVATION;
+ update(stmt);
+ } catch (SQLException e) {
+ if (e.toString().indexOf("Table already exists") == -1)
+ throw new RuntimeException(e);
+ }
+ }
+
+ /**
+ * Test database connection with simple SELECT command.
+ *
+ */
+ private String testDatabase() {
+ String result = null;
+ try {
+ Statement stmt = connection.createStatement(
+ ResultSet.TYPE_SCROLL_INSENSITIVE,
+ ResultSet.CONCUR_UPDATABLE);
+ ResultSet rs = stmt.executeQuery("SELECT COUNT(*) FROM "
+ + Resource.TABLE);
+ rs.next();
+ result = "rowcount for table test is " + rs.getObject(1).toString();
+ stmt.close();
+ } catch (SQLException e) {
+ throw new RuntimeException(e);
+ }
+ return result;
+ }
+
+ public Connection getConnection() {
+ return connection;
+ }
+
+ public Container getCategories() {
+ String q = "SELECT DISTINCT(" + Resource.PROPERTY_ID_CATEGORY
+ + ") FROM " + Resource.TABLE + " ORDER BY "
+ + Resource.PROPERTY_ID_CATEGORY;
+ try {
+ return new QueryContainer(q, connection,
+ ResultSet.TYPE_SCROLL_INSENSITIVE,
+ ResultSet.CONCUR_READ_ONLY);
+ } catch (SQLException e) {
+ throw new RuntimeException(e);
+ }
+
+ }
+
+ public Container getResources(String category) {
+ String q = "SELECT * FROM " + Resource.TABLE;
+ if (category != null) {
+ q += " WHERE " + Resource.PROPERTY_ID_CATEGORY + "='" + category
+ + "'"; // FIXME ->
+ // PreparedStatement!
+ }
+
+ try {
+ return new QueryContainer(q, connection,
+ ResultSet.TYPE_SCROLL_INSENSITIVE,
+ ResultSet.CONCUR_READ_ONLY);
+ } catch (SQLException e) {
+ throw new RuntimeException(e);
+ }
+
+ }
+
+ public Container getReservations(int[] resourceIds) {
+ String q = "SELECT * FROM " + Reservation.TABLE ;
+ if (resourceIds != null && resourceIds.length > 0) {
+ StringBuilder s = new StringBuilder();
+ for (int i = 0; i < resourceIds.length; i++) {
+ if (i > 0) {
+ s.append(",");
+ }
+ s.append(resourceIds[i]);
+ }
+ q += " HAVING " + Reservation.PROPERTY_ID_RESOURCE_ID + " IN (" + s
+ + ")";
+ }
+ q += " ORDER BY " + Reservation.PROPERTY_ID_RESERVED_FROM;
+ try {
+ QueryContainer qc = new QueryContainer(q, connection,
+ ResultSet.TYPE_SCROLL_INSENSITIVE,
+ ResultSet.CONCUR_READ_ONLY);
+ if (qc.size() < 1) {
+ return null;
+ } else {
+ return qc;
+ }
+ } catch (SQLException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+
+ public void addReservation(int resourceId, int reservedById,
+ Date reservedFrom, Date reservedTo, String description) {
+ // TODO swap dates if from>to
+ String checkQ = "SELECT count(*) FROM " + Reservation.TABLE + " WHERE "
+ + Reservation.PROPERTY_ID_RESOURCE_ID + "=? AND (("
+ + Reservation.PROPERTY_ID_RESERVED_FROM + ">=? AND "
+ + Reservation.PROPERTY_ID_RESERVED_FROM + "<=?) OR ("
+ + Reservation.PROPERTY_ID_RESERVED_TO + ">=? AND "
+ + Reservation.PROPERTY_ID_RESERVED_TO + "<=?) OR ("
+ + Reservation.PROPERTY_ID_RESERVED_FROM + "<=? AND "
+ + Reservation.PROPERTY_ID_RESERVED_TO + ">=?)"
+ +")";
+ System.err.println(checkQ);
+ String q = "INSERT INTO " + Reservation.TABLE + " ("
+ + Reservation.PROPERTY_ID_RESOURCE_ID + ","
+ + Reservation.PROPERTY_ID_RESERVED_BY_ID + ","
+ + Reservation.PROPERTY_ID_RESERVED_FROM + ","
+ + Reservation.PROPERTY_ID_RESERVED_TO + ","
+ + Reservation.PROPERTY_ID_DESCRIPTION + ")"
+ + "VALUES (?,?,?,?,?)";
+ synchronized (DB_URL) {
+ try {
+ PreparedStatement p = connection.prepareStatement(checkQ);
+ p.setInt(1, resourceId);
+ p.setTimestamp(2, new java.sql.Timestamp(reservedFrom.getTime()));
+ p.setTimestamp(3, new java.sql.Timestamp(reservedTo.getTime()));
+ p.setTimestamp(4, new java.sql.Timestamp(reservedFrom.getTime()));
+ p.setTimestamp(5, new java.sql.Timestamp(reservedTo.getTime()));
+ p.setTimestamp(6, new java.sql.Timestamp(reservedFrom.getTime()));
+ p.setTimestamp(7, new java.sql.Timestamp(reservedTo.getTime()));
+ p.execute();
+ ResultSet rs = p.getResultSet();
+ if (rs.next() && rs.getInt(1) > 0) {
+ // TODO custom exception
+ throw new RuntimeException("Not free!");
+ }
+ p = connection.prepareStatement(q);
+ p.setInt(1, resourceId);
+ p.setInt(2, reservedById);
+ p.setTimestamp(3,
+ new java.sql.Timestamp(reservedFrom.getTime()));
+ p.setTimestamp(4, new java.sql.Timestamp(reservedTo.getTime()));
+ p.setString(5, description);
+ p.execute();
+ } catch (Exception e) {
+ // TODO
+ System.err.println(e);
+ e.printStackTrace(System.err);
+ }
+ }
+ }
+
+ public Container getUsers() {
+ String q = "SELECT * FROM " + User.TABLE + " ORDER BY "
+ + User.PROPERTY_ID_FULLNAME;
+ try {
+ QueryContainer qc = new QueryContainer(q, connection,
+ ResultSet.TYPE_SCROLL_INSENSITIVE,
+ ResultSet.CONCUR_READ_ONLY);
+ return qc;
+ } catch (SQLException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ public void generateResources() {
+ String[][] resources = {
+ { "IT Mill Toolkit Manual", "the manual", "Books" },
+ { "IT Mill Toolkit for Dummies", "the hardcover version", "Books" },
+ { "Sony", "Old Sony video projector", "AV equipment" },
+ { "Sanyo", "Brand new hd-ready video projector", "AV equipment" },
+ { "Room 7", "Converence room in the lobby", "Conference rooms" },
+ { "Luokkahuone", "Classroom right next to IT Mill", "Conference rooms" },
+ { "Nintendo Wii", "Teh uber fun", "Entertainment" },
+ { "Playstation", "We don't actually have one", "Entertainment" }
+ };
+
+ String q = "INSERT INTO " + Resource.TABLE + "("
+ + Resource.PROPERTY_ID_NAME + ","
+ + Resource.PROPERTY_ID_DESCRIPTION + ","
+ + Resource.PROPERTY_ID_CATEGORY + ")" + " VALUES (?,?,?)";
+ try {
+ PreparedStatement stmt = connection.prepareStatement(q);
+ for (int i = 0; i < resources.length; i++) {
+ stmt.setString(1, resources[i][0]);
+ stmt.setString(2, resources[i][1]);
+ stmt.setString(3, resources[i][2]);
+ stmt.execute();
+ }
+ } catch (SQLException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ public void generateDemoUser() {
+ String q = "INSERT INTO USER (" + User.PROPERTY_ID_FULLNAME + ","
+ + User.PROPERTY_ID_EMAIL + "," + User.PROPERTY_ID_PASSWORD
+ + ") VALUES (?,?,?)";
+ try {
+ PreparedStatement stmt = connection.prepareStatement(q);
+ stmt.setString(1, "Demo User");
+ stmt.setString(2, "demo.user@itmill.com");
+ stmt.setString(3, "demo");
+ stmt.execute();
+ } catch (SQLException e) {
+ throw new RuntimeException(e);
+ }
+
+ }
+
+}