Java tutorial
/******************************************************************************* * Copyright (c) 2014 Ministry of Transport and Communications (Finland). * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * Semantum Oy - initial API and implementation *******************************************************************************/ package fi.semantum.strategia; import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; import java.nio.charset.Charset; import java.nio.file.Files; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Calendar; import java.util.Collection; import java.util.Collections; import java.util.Date; import java.util.Formatter; import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Set; import java.util.TreeMap; import java.util.TreeSet; import java.util.UUID; import javax.mail.MessagingException; import com.vaadin.data.Property.ValueChangeEvent; import com.vaadin.data.Property.ValueChangeListener; import com.vaadin.data.Validator; import com.vaadin.data.Validator.InvalidValueException; import com.vaadin.event.FieldEvents.TextChangeEvent; import com.vaadin.event.FieldEvents.TextChangeListener; import com.vaadin.server.FontAwesome; import com.vaadin.server.Page; import com.vaadin.server.Page.Styles; import com.vaadin.shared.ui.combobox.FilteringMode; import com.vaadin.ui.AbstractField; import com.vaadin.ui.AbstractLayout; import com.vaadin.ui.AbstractSelect.ItemCaptionMode; import com.vaadin.ui.Alignment; import com.vaadin.ui.Button; import com.vaadin.ui.Button.ClickEvent; import com.vaadin.ui.Button.ClickListener; import com.vaadin.ui.ComboBox; import com.vaadin.ui.Component; import com.vaadin.ui.CssLayout; import com.vaadin.ui.FormLayout; import com.vaadin.ui.HorizontalLayout; import com.vaadin.ui.Label; import com.vaadin.ui.ListSelect; import com.vaadin.ui.Panel; import com.vaadin.ui.PasswordField; import com.vaadin.ui.Table; import com.vaadin.ui.TextArea; import com.vaadin.ui.TextField; import com.vaadin.ui.VerticalLayout; import com.vaadin.ui.Window; import com.vaadin.ui.themes.ValoTheme; import fi.semantum.strategia.Main.TimeInterval; import fi.semantum.strategia.custom.OnDemandFileDownloader; import fi.semantum.strategia.custom.OnDemandFileDownloader.OnDemandStreamSource; import fi.semantum.strategia.widget.Account; import fi.semantum.strategia.widget.Base; import fi.semantum.strategia.widget.Database; import fi.semantum.strategia.widget.Datatype; import fi.semantum.strategia.widget.EnumerationDatatype; import fi.semantum.strategia.widget.Indicator; import fi.semantum.strategia.widget.Linkki; import fi.semantum.strategia.widget.Meter; import fi.semantum.strategia.widget.ObjectType; import fi.semantum.strategia.widget.Painopiste; import fi.semantum.strategia.widget.Pair; import fi.semantum.strategia.widget.Property; import fi.semantum.strategia.widget.Relation; import fi.semantum.strategia.widget.ResponsibilityInstance; import fi.semantum.strategia.widget.ResponsibilityModel; import fi.semantum.strategia.widget.Right; import fi.semantum.strategia.widget.Strategiakartta; import fi.semantum.strategia.widget.Tag; import fi.semantum.strategia.widget.Tavoite; import fi.semantum.strategia.widget.TimeConfiguration; public class Utils { public static final SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); public static String hash(String plainText) { Formatter formatter = new Formatter(); try { MessageDigest md5 = MessageDigest.getInstance("MD5"); byte[] digest = md5.digest(plainText.getBytes()); for (byte b : digest) { formatter.format("%02x", b); } return formatter.toString(); } catch (NoSuchAlgorithmException e) { // Nothing to do e.printStackTrace(); return null; } finally { formatter.close(); } } public static void modifyAccount(final Main main) { final Database database = main.getDatabase(); FormLayout content = new FormLayout(); content.setSizeFull(); final Label l = new Label(main.account.getId(database)); l.setCaption("Kyttjn nimi:"); l.setWidth("100%"); content.addComponent(l); final TextField tf = new TextField(); tf.setWidth("100%"); tf.addStyleName(ValoTheme.TEXTFIELD_SMALL); tf.addStyleName(ValoTheme.TEXTFIELD_BORDERLESS); tf.setCaption("Kyttjn nimi:"); tf.setId("loginUsernameField"); tf.setValue(main.account.getText(database)); content.addComponent(tf); final TextField tf2 = new TextField(); tf2.setWidth("100%"); tf2.addStyleName(ValoTheme.TEXTFIELD_SMALL); tf2.addStyleName(ValoTheme.TEXTFIELD_BORDERLESS); tf2.setCaption("Shkpostiosoite:"); tf2.setId("loginUsernameField"); tf2.setValue(main.account.getEmail()); content.addComponent(tf2); final PasswordField pf = new PasswordField(); pf.setCaption("Vanha salasana:"); pf.addStyleName(ValoTheme.TEXTFIELD_SMALL); pf.addStyleName(ValoTheme.TEXTFIELD_BORDERLESS); pf.setWidth("100%"); pf.setId("loginPasswordField"); content.addComponent(pf); final PasswordField pf2 = new PasswordField(); pf2.setCaption("Uusi salasana:"); pf2.addStyleName(ValoTheme.TEXTFIELD_SMALL); pf2.addStyleName(ValoTheme.TEXTFIELD_BORDERLESS); pf2.setWidth("100%"); pf2.setId("loginPasswordField"); content.addComponent(pf2); final PasswordField pf3 = new PasswordField(); pf3.setCaption("Uusi salasana uudestaan:"); pf3.addStyleName(ValoTheme.TEXTFIELD_SMALL); pf3.addStyleName(ValoTheme.TEXTFIELD_BORDERLESS); pf3.setWidth("100%"); pf3.setId("loginPasswordField"); content.addComponent(pf3); final Label err = new Label("Vr kyttjtunnus tai salasana"); err.addStyleName(ValoTheme.LABEL_FAILURE); err.addStyleName(ValoTheme.LABEL_TINY); err.setVisible(false); content.addComponent(err); HorizontalLayout buttons = new HorizontalLayout(); buttons.setSpacing(true); buttons.setMargin(false); Button apply = new Button("Tee muutokset"); buttons.addComponent(apply); final Window dialog = Dialogs.makeDialog(main, "450px", "480px", "Kyttjtilin asetukset", "Poistu", content, buttons); apply.addClickListener(new Button.ClickListener() { private static final long serialVersionUID = 1992235622970234624L; public void buttonClick(ClickEvent event) { String valueHash = Utils.hash(pf.getValue()); if (!valueHash.equals(main.account.getHash())) { err.setValue("Vr salasana"); err.setVisible(true); return; } if (pf2.isEmpty()) { err.setValue("Tyhj salasana ei kelpaa"); err.setVisible(true); return; } if (!pf2.getValue().equals(pf3.getValue())) { err.setValue("Uudet salasanat eivt tsm"); err.setVisible(true); return; } main.account.text = tf.getValue(); main.account.email = tf2.getValue(); main.account.hash = Utils.hash(pf2.getValue()); Updates.update(main, true); main.removeWindow(dialog); } }); } private static void makeAccountCombo(Main main, final Map<String, Account> accountMap, ComboBox users) { final Database database = main.getDatabase(); accountMap.clear(); String exist = (String) users.getValue(); users.removeAllItems(); for (Account a : Account.enumerate(database)) { accountMap.put(a.getId(database), a); users.addItem(a.getId(database)); if (exist != null) { if (a.getId(database).equals(exist)) users.select(a.getId(database)); } else { users.select(a.getId(database)); } } } private static void makeAccountTable(Database database, ComboBox users, final Map<String, Account> accountMap, final Table table) { table.removeAllItems(); Object selection = users.getValue(); Account state = accountMap.get(selection); if (state != null) { for (int i = 0; i < state.rights.size(); i++) { Right r = state.rights.get(i); table.addItem(new Object[] { r.map.getId(database), r.write ? "Muokkaus" : "Luku", r.recurse ? ALATASON_KARTAT : VALITTU_KARTTA }, i + 1); } } } public static final String ALATASON_KARTAT = "Alatason kartat"; public static final String VALITTU_KARTTA = "Valittu kartta"; public static String findFreshUserName(Validator validator) { String proposal = "Uusi kyttj"; try { validator.validate(proposal); return proposal; } catch (InvalidValueException e) { int counter = 2; while (true) { proposal = "Uusi kyttj " + counter++; try { validator.validate(proposal); return proposal; } catch (InvalidValueException e2) { } } } } public static void manage(final Main main) { final Database database = main.getDatabase(); VerticalLayout content = new VerticalLayout(); content.setSizeFull(); content.setSpacing(true); HorizontalLayout hl1 = new HorizontalLayout(); hl1.setSpacing(true); hl1.setWidth("100%"); final ComboBox users = new ComboBox(); users.setWidth("100%"); users.setNullSelectionAllowed(false); users.addStyleName(ValoTheme.COMBOBOX_SMALL); users.setCaption("Valitse kyttj:"); final Map<String, Account> accountMap = new HashMap<String, Account>(); makeAccountCombo(main, accountMap, users); for (Account a : Account.enumerate(database)) { accountMap.put(a.getId(database), a); users.addItem(a.getId(database)); users.select(a.getId(database)); } final Table table = new Table(); table.setSelectable(true); table.setMultiSelect(true); table.addStyleName(ValoTheme.TABLE_SMALL); table.addStyleName(ValoTheme.TABLE_SMALL); table.addStyleName(ValoTheme.TABLE_COMPACT); users.addValueChangeListener(new ValueChangeListener() { private static final long serialVersionUID = 5036991262418844060L; @Override public void valueChange(ValueChangeEvent event) { users.removeValueChangeListener(this); makeAccountCombo(main, accountMap, users); makeAccountTable(database, users, accountMap, table); users.addValueChangeListener(this); } }); final TextField tf = new TextField(); Validator nameValidator = new Validator() { private static final long serialVersionUID = -4779239111120669168L; @Override public void validate(Object value) throws InvalidValueException { String s = (String) value; if (s.isEmpty()) throw new InvalidValueException("Nimi ei saa olla tyhj"); if (accountMap.containsKey(s)) throw new InvalidValueException("Nimi on jo kytss"); } }; final Button save = new Button("Luo", new Button.ClickListener() { private static final long serialVersionUID = -6053708137324681886L; public void buttonClick(ClickEvent event) { if (!tf.isValid()) return; String pass = Long.toString(Math.abs(UUID.randomUUID().getLeastSignificantBits()), 36); Account.create(database, tf.getValue(), "", Utils.hash(pass)); Updates.update(main, true); makeAccountCombo(main, accountMap, users); makeAccountTable(database, users, accountMap, table); Dialogs.infoDialog(main, "Uusi kyttj '" + tf.getValue() + "' luotu", "Kyttjn salasana on " + pass + "", null); } }); save.addStyleName(ValoTheme.BUTTON_SMALL); final Button remove = new Button("Poista", new Button.ClickListener() { private static final long serialVersionUID = -5359199320445328801L; public void buttonClick(ClickEvent event) { Object selection = users.getValue(); Account state = accountMap.get(selection); // System cannot be removed if ("System".equals(state.getId(database))) return; state.remove(database); Updates.update(main, true); makeAccountCombo(main, accountMap, users); makeAccountTable(database, users, accountMap, table); } }); remove.addStyleName(ValoTheme.BUTTON_SMALL); tf.setWidth("100%"); tf.addStyleName(ValoTheme.TEXTFIELD_SMALL); tf.setCaption("Luo uusi kyttj nimell:"); tf.setValue(findFreshUserName(nameValidator)); tf.setCursorPosition(tf.getValue().length()); tf.setValidationVisible(true); tf.setInvalidCommitted(true); tf.setImmediate(true); tf.addTextChangeListener(new TextChangeListener() { private static final long serialVersionUID = -8274588731607481635L; @Override public void textChange(TextChangeEvent event) { tf.setValue(event.getText()); try { tf.validate(); } catch (InvalidValueException e) { save.setEnabled(false); return; } save.setEnabled(true); } }); tf.addValidator(nameValidator); if (!tf.isValid()) save.setEnabled(false); hl1.addComponent(users); hl1.setExpandRatio(users, 1.0f); hl1.setComponentAlignment(users, Alignment.BOTTOM_CENTER); hl1.addComponent(tf); hl1.setExpandRatio(tf, 1.0f); hl1.setComponentAlignment(tf, Alignment.BOTTOM_CENTER); hl1.addComponent(save); hl1.setExpandRatio(save, 0.0f); hl1.setComponentAlignment(save, Alignment.BOTTOM_CENTER); hl1.addComponent(remove); hl1.setExpandRatio(remove, 0.0f); hl1.setComponentAlignment(remove, Alignment.BOTTOM_CENTER); content.addComponent(hl1); content.setExpandRatio(hl1, 0.0f); table.addContainerProperty("Kartta", String.class, null); table.addContainerProperty("Oikeus", String.class, null); table.addContainerProperty("Laajuus", String.class, null); table.setWidth("100%"); table.setHeight("100%"); table.setNullSelectionAllowed(true); table.setMultiSelect(true); table.setCaption("Kyttjn oikeudet"); makeAccountTable(database, users, accountMap, table); content.addComponent(table); content.setExpandRatio(table, 1.0f); final Button removeRights = new Button("Poista valitut rivit", new Button.ClickListener() { private static final long serialVersionUID = 4699670345358079045L; public void buttonClick(ClickEvent event) { Object user = users.getValue(); Account state = accountMap.get(user); Object selection = table.getValue(); Collection<?> sel = (Collection<?>) selection; List<Right> toRemove = new ArrayList<Right>(); for (Object s : sel) { Integer index = (Integer) s; toRemove.add(state.rights.get(index - 1)); } for (Right r : toRemove) state.rights.remove(r); Updates.update(main, true); makeAccountTable(database, users, accountMap, table); } }); removeRights.addStyleName(ValoTheme.BUTTON_SMALL); table.addValueChangeListener(new ValueChangeListener() { private static final long serialVersionUID = 1188285609779556446L; @Override public void valueChange(ValueChangeEvent event) { Object selection = table.getValue(); Collection<?> sel = (Collection<?>) selection; if (sel.isEmpty()) removeRights.setEnabled(false); else removeRights.setEnabled(true); } }); final ComboBox mapSelect = new ComboBox(); mapSelect.setWidth("100%"); mapSelect.setNullSelectionAllowed(false); mapSelect.addStyleName(ValoTheme.COMBOBOX_SMALL); mapSelect.setCaption("Valitse kartta:"); for (Strategiakartta a : Strategiakartta.enumerate(database)) { mapSelect.addItem(a.uuid); mapSelect.setItemCaption(a.uuid, a.getText(database)); mapSelect.select(a.uuid); } final ComboBox rightSelect = new ComboBox(); rightSelect.setWidth("100px"); rightSelect.setNullSelectionAllowed(false); rightSelect.addStyleName(ValoTheme.COMBOBOX_SMALL); rightSelect.setCaption("Valitse oikeus:"); rightSelect.addItem("Muokkaus"); rightSelect.addItem("Luku"); rightSelect.select("Luku"); final ComboBox propagateSelect = new ComboBox(); propagateSelect.setWidth("130px"); propagateSelect.setNullSelectionAllowed(false); propagateSelect.addStyleName(ValoTheme.COMBOBOX_SMALL); propagateSelect.setCaption("Valitse laajuus:"); propagateSelect.addItem(VALITTU_KARTTA); propagateSelect.addItem(ALATASON_KARTAT); propagateSelect.select(VALITTU_KARTTA); final Button addRight = new Button("Lis rivi", new Button.ClickListener() { private static final long serialVersionUID = -4841787792917761055L; public void buttonClick(ClickEvent event) { Object user = users.getValue(); Account state = accountMap.get(user); String mapUUID = (String) mapSelect.getValue(); Strategiakartta map = database.find(mapUUID); String right = (String) rightSelect.getValue(); String propagate = (String) propagateSelect.getValue(); Right r = new Right(map, right.equals("Muokkaus"), propagate.equals(ALATASON_KARTAT)); state.rights.add(r); Updates.update(main, true); makeAccountTable(database, users, accountMap, table); } }); addRight.addStyleName(ValoTheme.BUTTON_SMALL); table.addValueChangeListener(new ValueChangeListener() { private static final long serialVersionUID = 6439090862804667322L; @Override public void valueChange(ValueChangeEvent event) { Object selection = table.getValue(); Collection<?> selected = (Collection<?>) selection; if (!selected.isEmpty()) { removeRights.setEnabled(true); } else { removeRights.setEnabled(false); } } }); HorizontalLayout hl2 = new HorizontalLayout(); hl2.setSpacing(true); hl2.setWidth("100%"); hl2.addComponent(removeRights); hl2.setComponentAlignment(removeRights, Alignment.TOP_LEFT); hl2.setExpandRatio(removeRights, 0.0f); hl2.addComponent(addRight); hl2.setComponentAlignment(addRight, Alignment.BOTTOM_LEFT); hl2.setExpandRatio(addRight, 0.0f); hl2.addComponent(mapSelect); hl2.setComponentAlignment(mapSelect, Alignment.BOTTOM_LEFT); hl2.setExpandRatio(mapSelect, 1.0f); hl2.addComponent(rightSelect); hl2.setComponentAlignment(rightSelect, Alignment.BOTTOM_LEFT); hl2.setExpandRatio(rightSelect, 0.0f); hl2.addComponent(propagateSelect); hl2.setComponentAlignment(propagateSelect, Alignment.BOTTOM_LEFT); hl2.setExpandRatio(propagateSelect, 0.0f); content.addComponent(hl2); content.setComponentAlignment(hl2, Alignment.BOTTOM_LEFT); content.setExpandRatio(hl2, 0.0f); final VerticalLayout vl = new VerticalLayout(); final Panel p = new Panel(); p.setWidth("100%"); p.setHeight("200px"); p.setContent(vl); final TimeConfiguration tc = TimeConfiguration.getInstance(database); final TextField tf2 = new TextField(); tf2.setWidth("200px"); tf2.addStyleName(ValoTheme.TEXTFIELD_SMALL); tf2.setCaption("Strategiakartan mritysaika:"); tf2.setValue(tc.getRange()); tf2.setCursorPosition(tf.getValue().length()); tf2.setValidationVisible(true); tf2.setInvalidCommitted(true); tf2.setImmediate(true); tf2.addTextChangeListener(new TextChangeListener() { private static final long serialVersionUID = -8274588731607481635L; @Override public void textChange(TextChangeEvent event) { tf2.setValue(event.getText()); try { tf2.validate(); tc.setRange(event.getText()); updateYears(database, vl); Updates.update(main, true); } catch (InvalidValueException e) { return; } } }); tf2.addValidator(new Validator() { private static final long serialVersionUID = -4779239111120669168L; @Override public void validate(Object value) throws InvalidValueException { String s = (String) value; TimeInterval ti = TimeInterval.parse(s); long start = ti.startYear; long end = ti.endYear; if (start < 2015) throw new InvalidValueException("Alkuvuosi ei voi olla aikaisempi kuin 2015."); if (end > 2025) throw new InvalidValueException("Pttymisvuosi ei voi olla myhisempi kuin 2025."); if (end - start > 9) throw new InvalidValueException("Strategiakartta ei tue yli 10 vuoden tarkasteluja."); } }); content.addComponent(tf2); content.setComponentAlignment(tf2, Alignment.BOTTOM_LEFT); content.setExpandRatio(tf2, 0.0f); updateYears(database, vl); content.addComponent(p); content.setComponentAlignment(p, Alignment.BOTTOM_LEFT); content.setExpandRatio(p, 0.0f); HorizontalLayout buttons = new HorizontalLayout(); buttons.setSpacing(true); buttons.setMargin(false); Dialogs.makeDialog(main, main.dialogWidth(), main.dialogHeight(0.8), "Hallinnoi strategiakarttaa", "Sulje", content, buttons); } public static void updateYears(final Database database, final VerticalLayout vl) { vl.removeAllComponents(); final TimeConfiguration tc = TimeConfiguration.getInstance(database); TimeInterval ti = TimeInterval.parse(tc.getRange()); for (int i = ti.startYear; i <= ti.endYear; i++) { final int year = i; HorizontalLayout hl = new HorizontalLayout(); hl.setSpacing(true); String caption = Integer.toString(i) + (tc.isFrozen(i) ? " Muutokset estetty" : " Muokattavissa"); Label l = new Label(caption); l.setWidth("250px"); l.setHeight("100%"); hl.addComponent(l); Button b = new Button(tc.isFrozen(i) ? "Avaa muokattavaksi" : "Est muutokset"); b.addStyleName(ValoTheme.BUTTON_SMALL); b.addClickListener(new ClickListener() { private static final long serialVersionUID = 556680407448842136L; @Override public void buttonClick(ClickEvent event) { if (tc.isFrozen(year)) { tc.unfreeze(year); } else { tc.freeze(year); } updateYears(database, vl); } }); b.setWidth("200px"); hl.addComponent(b); //hl.setWidth("100%"); vl.addComponent(hl); } } public static void setUserMeter(final Main main, final Base base, final Meter m) { final Database database = main.getDatabase(); final Window subwindow = new Window("Aseta mittarin arvo", new VerticalLayout()); subwindow.setModal(true); subwindow.setWidth("350px"); subwindow.setResizable(false); final VerticalLayout winLayout = (VerticalLayout) subwindow.getContent(); winLayout.setMargin(true); winLayout.setSpacing(true); String caption = m.getCaption(database); if (caption != null && !caption.isEmpty()) { final Label header = new Label(caption); header.addStyleName(ValoTheme.LABEL_LARGE); winLayout.addComponent(header); } final Indicator indicator = m.getPossibleIndicator(database); if (indicator == null) return; Datatype dt = indicator.getDatatype(database); if (!(dt instanceof EnumerationDatatype)) return; final Label l = new Label("Selite: " + indicator.getValueShortComment()); AbstractField<?> forecastField = dt.getEditor(main, base, indicator, true, new CommentCallback() { @Override public void runWithComment(String shortComment, String comment) { l.setValue("Selite: " + indicator.getValueShortComment()); } @Override public void canceled() { } }); forecastField.setWidth("100%"); forecastField.setCaption("Ennuste"); winLayout.addComponent(forecastField); AbstractField<?> currentField = dt.getEditor(main, base, indicator, false, new CommentCallback() { @Override public void runWithComment(String shortComment, String comment) { l.setValue("Selite: " + indicator.getValueShortComment()); } @Override public void canceled() { } }); currentField.setWidth("100%"); currentField.setCaption("Toteuma"); winLayout.addComponent(currentField); winLayout.addComponent(l); l.setWidth("100%"); winLayout.setComponentAlignment(l, Alignment.BOTTOM_CENTER); HorizontalLayout hl = new HorizontalLayout(); winLayout.addComponent(hl); winLayout.setComponentAlignment(hl, Alignment.BOTTOM_CENTER); Button ok = new Button("Sulje", new Button.ClickListener() { private static final long serialVersionUID = 1364802814012491490L; public void buttonClick(ClickEvent event) { main.removeWindow(subwindow); } }); Button define = new Button("Mrit", new Button.ClickListener() { private static final long serialVersionUID = 1364802814012491490L; public void buttonClick(ClickEvent event) { Meter.editMeter(main, base, m); } }); hl.addComponent(ok); hl.setComponentAlignment(ok, Alignment.BOTTOM_LEFT); hl.addComponent(define); hl.setComponentAlignment(define, Alignment.BOTTOM_LEFT); main.addWindow(subwindow); } public static void saveCurrentState(final Main main) { VerticalLayout content = new VerticalLayout(); content.setSizeFull(); HorizontalLayout hl1 = new HorizontalLayout(); hl1.setSpacing(true); hl1.setWidth("100%"); final Map<String, UIState> stateMap = new HashMap<String, UIState>(); for (UIState s : main.account.uiStates) stateMap.put(s.name, s); final TextField tf = new TextField(); final Button save = new Button("Tallenna nkym", new Button.ClickListener() { private static final long serialVersionUID = 2449606920686729881L; public void buttonClick(ClickEvent event) { if (!tf.isValid()) return; String name = tf.getValue(); Page.getCurrent().getJavaScript().execute("doSaveBrowserState('" + name + "');"); } }); tf.setWidth("100%"); tf.addStyleName(ValoTheme.TEXTFIELD_SMALL); tf.setCaption("Tallenna nykyinen nkym nimell:"); tf.setValue("Uusi nkym"); tf.setCursorPosition(tf.getValue().length()); tf.setValidationVisible(true); tf.setInvalidCommitted(true); tf.setImmediate(true); tf.addTextChangeListener(new TextChangeListener() { private static final long serialVersionUID = -8274588731607481635L; @Override public void textChange(TextChangeEvent event) { tf.setValue(event.getText()); try { tf.validate(); } catch (InvalidValueException e) { save.setEnabled(false); return; } save.setEnabled(true); } }); tf.addValidator(new Validator() { private static final long serialVersionUID = -4779239111120669168L; @Override public void validate(Object value) throws InvalidValueException { String s = (String) value; if (s.isEmpty()) throw new InvalidValueException("Nimi ei saa olla tyhj"); if (stateMap.containsKey(s)) throw new InvalidValueException("Nimi on jo kytss"); } }); if (!tf.isValid()) save.setEnabled(false); hl1.addComponent(tf); hl1.setExpandRatio(tf, 1.0f); hl1.addComponent(save); hl1.setExpandRatio(save, 0.0f); hl1.setComponentAlignment(save, Alignment.BOTTOM_CENTER); content.addComponent(hl1); content.setExpandRatio(hl1, 0.0f); final ListSelect table = new ListSelect(); table.setWidth("100%"); table.setHeight("100%"); table.setNullSelectionAllowed(true); table.setMultiSelect(true); table.setCaption("Tallennetut nkymt"); for (UIState state : main.account.uiStates) { table.addItem(state.name); } content.addComponent(table); content.setExpandRatio(table, 1.0f); final Button remove = new Button("Poista valitut nkymt"); table.addValueChangeListener(new ValueChangeListener() { private static final long serialVersionUID = 6439090862804667322L; @Override public void valueChange(ValueChangeEvent event) { Object selection = table.getValue(); Collection<?> selected = (Collection<?>) selection; if (!selected.isEmpty()) { remove.setEnabled(true); } else { remove.setEnabled(false); } } }); remove.setEnabled(false); content.addComponent(remove); content.setComponentAlignment(remove, Alignment.MIDDLE_LEFT); content.setExpandRatio(remove, 0.0f); HorizontalLayout buttons = new HorizontalLayout(); buttons.setSpacing(true); buttons.setMargin(false); final Window dialog = Dialogs.makeDialog(main, "Nkymien hallinta", "Sulje", content, buttons); remove.addClickListener(new Button.ClickListener() { private static final long serialVersionUID = -4680588998085550908L; public void buttonClick(ClickEvent event) { Object selection = table.getValue(); Collection<?> selected = (Collection<?>) selection; if (!selected.isEmpty()) { for (Object o : selected) { UIState state = stateMap.get(o); if (state != null) main.account.uiStates.remove(state); } Updates.update(main, true); } main.removeWindow(dialog); } }); } public static void addMap(final Main main, final Strategiakartta parent) { final Database database = main.getDatabase(); FormLayout content = new FormLayout(); content.setSizeFull(); // final TextField tf = new TextField(); // tf.setCaption("Kartan tunniste:"); // tf.setValue("tunniste"); // tf.setWidth("100%"); // content.addComponent(tf); final TextField tf2 = new TextField(); tf2.setCaption("Kartan nimi:"); tf2.setValue("Uusi kartta"); tf2.setWidth("100%"); content.addComponent(tf2); final ComboBox combo = new ComboBox(); combo.setCaption("Kartan tyyppi:"); combo.setNullSelectionAllowed(false); combo.setWidth("100%"); content.addComponent(combo); Collection<Base> subs = Strategiakartta.availableLevels(database); for (Base b : subs) { combo.addItem(b.uuid); combo.setItemCaption(b.uuid, b.getText(database)); combo.select(b.uuid); } HorizontalLayout buttons = new HorizontalLayout(); buttons.setSpacing(true); buttons.setMargin(true); Button ok = new Button("Lis"); buttons.addComponent(ok); final Window dialog = Dialogs.makeDialog(main, "450px", "340px", "Lis alatason kartta", "Peruuta", content, buttons); ok.addClickListener(new Button.ClickListener() { private static final long serialVersionUID = 1422158448876521843L; public void buttonClick(ClickEvent event) { String name = tf2.getValue(); String typeUUID = (String) combo.getValue(); Base type = database.find(typeUUID); database.newMap(main, parent, "", name, type); Updates.updateJS(main, true); main.removeWindow(dialog); } }); } public static void addImplementationMap(final Main main, final Tavoite goal) { final Database database = main.getDatabase(); try { Base subType = goal.getPossibleSubmapType(database); if (subType != null) { goal.ensureImplementationMap(main); Updates.updateJS(main, true); return; } } catch (Exception e) { e.printStackTrace(); return; } FormLayout content = new FormLayout(); content.setSizeFull(); final ComboBox combo = new ComboBox(); combo.setCaption("Kartan tyyppi:"); combo.setNullSelectionAllowed(false); combo.setWidth("100%"); content.addComponent(combo); Collection<Base> subs = Strategiakartta.availableLevels(database); for (Base b : subs) { combo.addItem(b.uuid); combo.setItemCaption(b.uuid, b.getText(database)); combo.select(b.uuid); } HorizontalLayout buttons = new HorizontalLayout(); buttons.setSpacing(true); buttons.setMargin(true); Button ok = new Button("Lis"); buttons.addComponent(ok); final Window dialog = Dialogs.makeDialog(main, "450px", "340px", "Lis alatason kartta", "Peruuta", content, buttons); ok.addClickListener(new Button.ClickListener() { private static final long serialVersionUID = 1422158448876521843L; public void buttonClick(ClickEvent event) { String typeUUID = (String) combo.getValue(); Base type = database.find(typeUUID); Strategiakartta parent = database.getMap(goal); Strategiakartta newMap = database.newMap(main, parent, "", "", type); newMap.addRelation(Relation.find(database, Relation.IMPLEMENTS), goal); for (Painopiste pp : goal.painopisteet) { Tavoite.createCopy(main, newMap, pp); } Updates.updateJS(main, true); main.removeWindow(dialog); } }); } public static void insertRootMap(final Main main, final Strategiakartta currentRoot) { final Database database = main.getDatabase(); FormLayout content = new FormLayout(); content.setSizeFull(); final TextField tf = new TextField(); tf.setCaption("Kartan tunniste:"); tf.setValue("tunniste"); tf.setWidth("100%"); content.addComponent(tf); final TextField tf2 = new TextField(); tf2.setCaption("Kartan nimi:"); tf2.setValue("Uusi kartta"); tf2.setWidth("100%"); content.addComponent(tf2); final ComboBox combo = new ComboBox(); combo.setCaption("Kartan tyyppi:"); combo.setNullSelectionAllowed(false); combo.setWidth("100%"); content.addComponent(combo); Collection<Base> subs = Strategiakartta.availableLevels(database); for (Base b : subs) { combo.addItem(b.uuid); combo.setItemCaption(b.uuid, b.getText(database)); combo.select(b.uuid); } HorizontalLayout buttons = new HorizontalLayout(); buttons.setSpacing(true); buttons.setMargin(true); Button ok = new Button("Lis"); buttons.addComponent(ok); final Window dialog = Dialogs.makeDialog(main, "450px", "340px", "Lis alatason kartta", "Peruuta", content, buttons); ok.addClickListener(new Button.ClickListener() { private static final long serialVersionUID = 1422158448876521843L; public void buttonClick(ClickEvent event) { String id = tf.getValue(); String name = tf2.getValue(); String typeUUID = (String) combo.getValue(); Base type = database.find(typeUUID); Strategiakartta uusi = database.newMap(main, null, id, name, type); uusi.addAlikartta(currentRoot); Updates.updateJS(main, true); main.removeWindow(dialog); } }); } public static void print(final Main main) { VerticalLayout content = new VerticalLayout(); HorizontalLayout buttons = new HorizontalLayout(); buttons.setSpacing(true); final Button ok = new Button("Lataa"); ok.addClickListener(new ClickListener() { private static final long serialVersionUID = 5350320436995864012L; @Override public void buttonClick(ClickEvent event) { ok.setEnabled(false); } }); buttons.addComponent(ok); final String svgText = main.pdf.svg; final OnDemandFileDownloader dl = new OnDemandFileDownloader(new OnDemandStreamSource() { private static final long serialVersionUID = -3866190768030858133L; File temp; Date date = new Date(); @Override public InputStream getStream() { String uuid = UUID.randomUUID().toString(); File printing = new File(Main.baseDirectory(), "printing"); temp = new File(printing, uuid + ".pdf"); if (svgText != null) { File htmlFile = new File(printing, uuid + ".html"); File script = new File(printing, uuid + ".js"); try { String html = PhantomJSDriver.printHtml(svgText, Main.getAppFile("print.html").getParentFile().getAbsolutePath()); Files.write(htmlFile.toPath(), html.getBytes(Charset.forName("UTF-8"))); String browserUrl = htmlFile.toURI().toURL().toString(); String printCommand = PhantomJSDriver.printCommand(browserUrl, temp.getAbsolutePath()); Files.write(script.toPath(), printCommand.getBytes()); PhantomJSDriver.execute(script); return new FileInputStream(temp); } catch (IOException e) { e.printStackTrace(); } } throw new IllegalStateException(); } @Override public void onRequest() { } @Override public long getFileSize() { return temp.length(); } @Override public String getFileName() { return "Strategiakartta_" + Utils.dateString(date) + ".pdf"; } }); dl.getResource().setCacheTime(0); dl.extend(ok); final Window dialog = Dialogs.makeDialog(main, "420px", "135px", "Haluatko ladata kartan PDF-muodossa?", "Sulje", content, buttons); } public static void addView(final Main main, final Strategiakartta map) { final Database database = main.getDatabase(); FormLayout content = new FormLayout(); content.setSizeFull(); final TextField tf = new TextField(); tf.setCaption("Nkymn tunniste:"); tf.setValue("tunniste"); tf.setWidth("100%"); content.addComponent(tf); final TextField tf2 = new TextField(); tf2.setCaption("Nkymn nimi:"); tf2.setValue("Uusi nkym"); tf2.setWidth("100%"); content.addComponent(tf2); final ComboBox combo = new ComboBox(); combo.setCaption("Kartan tyyppi:"); combo.setNullSelectionAllowed(false); combo.setWidth("100%"); content.addComponent(combo); Property levelProperty = Property.find(database, Property.LEVEL); ObjectType level = database.find((String) levelProperty.getPropertyValue(map)); Collection<Base> subs = Strategiakartta.availableLevels(database); for (Base b : subs) { combo.addItem(b.uuid); combo.setItemCaption(b.uuid, b.getText(database)); combo.select(b.uuid); } final ComboBox combo2 = new ComboBox(); combo2.setCaption("Aihetunniste:"); combo2.setNullSelectionAllowed(false); combo2.setWidth("100%"); content.addComponent(combo2); for (Tag t : Tag.enumerate(database)) { combo2.addItem(t.uuid); combo2.setItemCaption(t.uuid, t.getId(database)); combo2.select(t.uuid); } HorizontalLayout buttons = new HorizontalLayout(); buttons.setSpacing(true); buttons.setMargin(true); Button ok = new Button("Lis"); buttons.addComponent(ok); final Window dialog = Dialogs.makeDialog(main, "450px", "380px", "Lis nkym", "Peruuta", content, buttons); ok.addClickListener(new Button.ClickListener() { private static final long serialVersionUID = 1422158448876521843L; public void buttonClick(ClickEvent event) { String id = tf.getValue(); String name = tf2.getValue(); String typeUUID = (String) combo.getValue(); Base type = database.find(typeUUID); String tagUUID = (String) combo2.getValue(); Tag tag = (Tag) database.find(tagUUID); Strategiakartta newMap = database.newMap(main, main.uiState.current, id, name + " (nkym)", type); newMap.generators.add(tag); Updates.updateJS(main, true); main.removeWindow(dialog); } }); } public static interface CommentCallback { public void runWithComment(String shortComment, String comment); public void canceled(); } public static class AbstractCommentCallback implements CommentCallback { @Override public void runWithComment(String shortComment, String comment) { } @Override public void canceled() { } } public static void editTextAndId(final Main main, String title, final Base container) { final Database database = main.getDatabase(); final Window subwindow = new Window(title, new VerticalLayout()); subwindow.setModal(true); subwindow.setWidth("400px"); subwindow.setHeight("500px"); subwindow.setResizable(false); VerticalLayout winLayout = (VerticalLayout) subwindow.getContent(); winLayout.setMargin(true); winLayout.setSpacing(true); final TextField tf = new TextField(); tf.setCaption("Lyhytnimi:"); tf.addStyleName(ValoTheme.TEXTFIELD_SMALL); tf.setValue(container.getId(database)); tf.setWidth("100%"); winLayout.addComponent(tf); final TextArea ta = new TextArea(); ta.setCaption("Teksti:"); ta.setValue(container.getText(database)); ta.setWidth("100%"); ta.setHeight("290px"); winLayout.addComponent(ta); Button save = new Button("Tallenna", new Button.ClickListener() { private static final long serialVersionUID = 6641880870005364983L; public void buttonClick(ClickEvent event) { String idValue = tf.getValue(); String value = ta.getValue(); main.removeWindow(subwindow); container.modifyId(main, idValue); container.modifyText(main, value); Collection<String> tags = Tag.extractTags(value); database.assertTags(tags); ArrayList<Tag> tagObjects = new ArrayList<Tag>(); for (String s : tags) tagObjects.add(database.getOrCreateTag(s)); container.assertRelatedTags(database, tagObjects); Updates.update(main, true); Property emails = Property.find(database, Property.EMAIL); String addr = emails.getPropertyValue(container); if (addr != null && !addr.isEmpty()) { String[] addrs = addr.split(","); if (addrs.length > 0) { try { Email.send(addrs, "Muutos strategiakartassa: " + container.getId(database), "Kyttj " + main.account.getId(database) + " on muuttanut strategiakarttaa.<br/><br/>Lyhytnimi: " + container.getId(database) + "<br/><br/>Teksti: " + container.getText(database)); } catch (MessagingException e) { e.printStackTrace(); } } } } }); Button discard = new Button("Peru muutokset", new Button.ClickListener() { private static final long serialVersionUID = -784522457615993823L; public void buttonClick(ClickEvent event) { Updates.update(main, true); main.removeWindow(subwindow); } }); HorizontalLayout hl2 = new HorizontalLayout(); hl2.setSpacing(true); hl2.addComponent(save); hl2.addComponent(discard); winLayout.addComponent(hl2); winLayout.setComponentAlignment(hl2, Alignment.MIDDLE_CENTER); main.addWindow(subwindow); ta.setCursorPosition(ta.getValue().length()); } public static Button tagButton(final Database database, String prefix, String tag, final int index) { Tag t = database.getOrCreateTag(tag); Styles styles = Page.getCurrent().getStyles(); styles.add(".fi_semantum_strategia div.v-button." + prefix + "tag" + index + " { opacity: 1.0; box-shadow:none; color: #000000; background-image: linear-gradient(" + t.color + " 0%, " + t.color + " 100%); }"); Button tagButton = new Button(); tagButton.setEnabled(false); tagButton.setCaption(tag); tagButton.addStyleName(prefix + "tag" + index); return tagButton; } public static void fillTagEditor(final Database database, final AbstractLayout layout, final List<String> tags, final boolean allowRemove) { layout.removeAllComponents(); for (int i = 0; i < tags.size(); i++) { String tag = tags.get(i); HorizontalLayout hl = new HorizontalLayout(); if (allowRemove) { final int index = i; Button b = new Button(); b.addStyleName(ValoTheme.BUTTON_BORDERLESS); b.setIcon(FontAwesome.TIMES_CIRCLE); b.addClickListener(new ClickListener() { private static final long serialVersionUID = -4473258383318654850L; @Override public void buttonClick(ClickEvent event) { tags.remove(index); fillTagEditor(database, layout, tags, allowRemove); } }); hl.addComponent(b); } Button tagButton = tagButton(database, "dialog", tag, i); hl.addComponent(tagButton); hl.setComponentAlignment(tagButton, Alignment.MIDDLE_LEFT); layout.addComponent(hl); } } static class TagCombo extends ComboBox { private static final long serialVersionUID = 5930055496801663683L; String customFilterString; @Override public void changeVariables(Object source, Map<String, Object> variables) { super.changeVariables(source, variables); customFilterString = (String) variables.get("filter"); } } public static void editTags(final Main main, String title, final Base container) { final Database database = main.getDatabase(); final Window subwindow = new Window(title, new VerticalLayout()); subwindow.setModal(true); subwindow.setWidth("400px"); subwindow.setHeight("360px"); subwindow.setResizable(true); VerticalLayout winLayout = (VerticalLayout) subwindow.getContent(); winLayout.setMargin(true); winLayout.setSpacing(true); // Add some content; a label and a close-button final List<String> tags = new ArrayList<String>(); for (Tag t : container.getRelatedTags(database)) tags.add(t.getId(database)); final CssLayout vl = new CssLayout(); vl.setCaption("Kytss olevat aihetunnisteet:"); fillTagEditor(database, vl, tags, Account.canWrite(main, container)); winLayout.addComponent(vl); HorizontalLayout hl = new HorizontalLayout(); hl.setWidth("100%"); hl.setSpacing(true); final TagCombo combo = new TagCombo(); final CustomLazyContainer comboContainer = new CustomLazyContainer(database, combo, Tag.enumerate(database)); combo.setWidth("100%"); combo.setCaption("Uusi aihetunniste:"); combo.setInputPrompt("valitse listasta tai kirjoita"); combo.setFilteringMode(FilteringMode.STARTSWITH); combo.setTextInputAllowed(true); combo.setImmediate(true); combo.setNullSelectionAllowed(false); combo.setInvalidAllowed(true); combo.setInvalidCommitted(true); combo.setItemCaptionMode(ItemCaptionMode.PROPERTY); combo.setItemCaptionPropertyId("id"); //should set combo.setContainerDataSource(comboContainer); hl.addComponent(combo); hl.setExpandRatio(combo, 1.0f); Button add = new Button("Lis", new Button.ClickListener() { private static final long serialVersionUID = -2848576385076605664L; public void buttonClick(ClickEvent event) { String filter = (String) combo.getValue(); if (filter != null && filter.length() > 0) { Tag t = database.getOrCreateTag(filter); if (tags.contains(t.getId(database))) return; tags.add(t.getId(database)); fillTagEditor(database, vl, tags, main.account != null); combo.clear(); } } }); hl.addComponent(add); hl.setComponentAlignment(add, Alignment.BOTTOM_LEFT); hl.setExpandRatio(add, 0.0f); winLayout.addComponent(hl); Button close = new Button("Tallenna", new Button.ClickListener() { private static final long serialVersionUID = -451523776456589591L; public void buttonClick(ClickEvent event) { main.removeWindow(subwindow); List<Tag> newTags = new ArrayList<Tag>(); for (String s : tags) newTags.add(database.getOrCreateTag(s)); container.setRelatedTags(database, newTags); Updates.update(main, true); } }); Button discard = new Button("Peru muutokset", new Button.ClickListener() { private static final long serialVersionUID = -2387057110951581993L; public void buttonClick(ClickEvent event) { main.removeWindow(subwindow); } }); HorizontalLayout hl2 = new HorizontalLayout(); hl2.setSpacing(true); hl2.addComponent(close); hl2.addComponent(discard); winLayout.addComponent(hl2); winLayout.setComponentAlignment(hl2, Alignment.MIDDLE_CENTER); main.addWindow(subwindow); } public static void loseFocus(Component parent) { while (parent != null) { if (parent instanceof Component.Focusable) { ((Component.Focusable) parent).focus(); break; } else { parent = parent.getParent(); } } } public static Base getPossibleImplemented(Database db, Base b) { Relation implementsRelation = Relation.find(db, Relation.IMPLEMENTS); Pair p = implementsRelation.getPossibleRelation(b); if (p != null) { return db.find(p.second); } return null; } public static boolean doesImplement(Database db, Base b, Base target) { return doesImplement(db, b, target, new HashMap<Base, Boolean>()); } private static boolean doesImplement(Database db, Base b, Base target, Map<Base, Boolean> cache) { Boolean c = cache.get(b); if (c != null) return c; if (b.equals(target)) { cache.put(b, true); return true; } Relation implementsRelation = Relation.find(db, Relation.IMPLEMENTS); for (Base b2 : b.getRelatedObjects(db, implementsRelation)) { if (doesImplement(db, b2, target, cache)) { cache.put(b, true); return true; } } cache.put(b, false); return false; } public static Set<Base> getImplementors(Database db, Base target, Map<Base, Boolean> cache) { Set<Base> result = new HashSet<Base>(); for (Base b : db.enumerate()) { if (doesImplement(db, b, target, cache)) result.add(b); } return result; } // public static boolean getManyImplementor(Database database, ObjectType type) { // // Property p = Property.find(database, Property.MANY_IMPLEMENTOR); // return Boolean.parseBoolean(p.getPropertyValue(type)); // // } public static ObjectType getOwnGoalType(Database database, Strategiakartta map) { Property levelProperty = Property.find(database, Property.LEVEL); ObjectType level = database.find((String) levelProperty.getPropertyValue(map)); Property goalTypeProperty = Property.find(database, Property.OWN_GOAL_TYPE); String goalTypeUUID = goalTypeProperty.getPropertyValue(level); return database.find(goalTypeUUID); } public static ObjectType getGoalType(Database database, Strategiakartta map) { Property levelProperty = Property.find(database, Property.LEVEL); ObjectType level = database.find((String) levelProperty.getPropertyValue(map)); Property goalTypeProperty = Property.find(database, Property.GOAL_TYPE); String goalTypeUUID = goalTypeProperty.getPropertyValue(level); return database.find(goalTypeUUID); } public static String describeDate(Date d) { return describeDate(new Date(), d); } public static String describeDate(Date now, Date d) { long diff = now.getTime() - d.getTime(); String date = ""; if (diff < 1000 * 60) { date = "Hetki sitten"; } else if (diff < 1000 * 60 * 60) { date = "" + (diff / (1000 * 60)) + " min sitten"; } else if (diff < 1000 * 60 * 60 * 24) { date = "" + (diff / (1000 * 60 * 60)) + " h sitten"; } else if (diff < 1000 * 60 * 60 * 24 * 7) { date = "" + (diff / (1000 * 60 * 60 * 24)) + " piv sitten"; } else { date = Utils.sdf.format(d); } return date; } public static void modifyValidity(Main main, Base base, String newValidity) { Property aika = Property.find(main.getDatabase(), Property.AIKAVALI); aika.set(main, base, newValidity); } public static String getValidity(Database database, Base base) { Property aika = Property.find(database, Property.AIKAVALI); String result = aika.getPropertyValue(base); if (result == null) result = Property.AIKAVALI_KAIKKI; return result; } public static Set<Base> getImplementationSet(Database database, Base b) { Relation implementsRelation = Relation.find(database, Relation.IMPLEMENTS); Collection<Base> imp = b.getRelatedObjects(database, implementsRelation); if (imp.isEmpty()) return Collections.emptySet(); Set<Base> result = new TreeSet<Base>(); if (b instanceof Painopiste) { result.add(((Painopiste) b).getGoal(database)); } for (Base b2 : imp) { result.add(b2); Set<Base> bs = getImplementationSet(database, b2); result.addAll(bs); } return result; } public static Collection<Base> getDirectImplementors(Database database, Base b) { return getDirectImplementors(database, b, Property.AIKAVALI_KAIKKI); } public static Collection<Base> getDirectImplementors(Database database, Base b, String requiredValidityPeriod) { return getDirectImplementors(database, b, true, requiredValidityPeriod); } public static Collection<Base> getDirectImplementors(Database database, Base b, boolean filterMaps, String requiredValidityPeriod) { ArrayList<Base> implementors = new ArrayList<Base>( database.getInverse(b, Relation.find(database, Relation.IMPLEMENTS))); Collections.sort(implementors); if (implementors.isEmpty()) return Collections.emptyList(); TreeMap<Double, Base> sorting = new TreeMap<Double, Base>(); Strategiakartta map = database.getMap(b); Property aika = Property.find(database, Property.AIKAVALI); for (int i = 0; i < implementors.size(); i++) { Base b2 = implementors.get(i); if (filterMaps && b2 instanceof Strategiakartta) continue; String a = aika.getPropertyValue(b2); if (Utils.acceptTime(a, requiredValidityPeriod)) { Strategiakartta child = database.getMap(b2); double key = 1.0 / Double.valueOf(i + 1); for (int j = 0; j < map.alikartat.length; j++) { Linkki l = map.alikartat[j]; if (l.uuid.equals(child.uuid)) key = j + 2; } sorting.put(key, b2); } } return sorting.values(); } public static List<String> excelRow(String... cells) { ArrayList<String> result = new ArrayList<String>(); for (String s : cells) result.add(s); return result; } public static String dateString(Date date) { Calendar cal = Calendar.getInstance(); cal.setTime(date); int year = cal.get(Calendar.YEAR); int month = cal.get(Calendar.MONTH); int day = cal.get(Calendar.DAY_OF_MONTH); int hours = cal.get(Calendar.HOUR_OF_DAY); int minutes = cal.get(Calendar.MINUTE); int seconds = cal.get(Calendar.SECOND); return "Strategiakartta_" + day + "_" + month + "_" + year + "__" + hours + "_" + minutes + "_" + seconds; } public static String hexI(int i) { if (i < 10) return "" + i; else { char offset = (char) (i - 10); char c = (char) ('A' + offset); return "" + c; } } public static String hex(double value) { int i = (int) value; int upper = i >> 4; int lower = i & 15; return hexI(upper) + hexI(lower); } public static String trafficColor(double value) { double redR = 218.0; double redG = 37.0; double redB = 29.0; double yellowR = 244.0; double yellowG = 192.0; double yellowB = 0.0; double greenR = 0.0; double greenG = 146.0; double greenB = 63.0; if (value < 0.5) { double r = (1 - 2.0 * value) * redR + (2.0 * value) * yellowR; double g = (1 - 2.0 * value) * redG + (2.0 * value) * yellowG; double b = (1 - 2.0 * value) * redB + (2.0 * value) * yellowB; return "#" + hex(r) + hex(g) + hex(b); } else { double r = (2.0 * value - 1) * greenR + (2 - 2.0 * value) * yellowR; double g = (2.0 * value - 1) * greenG + (2 - 2.0 * value) * yellowG; double b = (2.0 * value - 1) * greenB + (2 - 2.0 * value) * yellowB; return "#" + hex(r) + hex(g) + hex(b); } } public static String printPath(Database database, Base b) { StringBuilder result = new StringBuilder(); Strategiakartta map = b.getMap(database); result.append(b.getText(database)); Strategiakartta parent = map.getPossibleParent(database); while (parent != null) { result.append(" / "); result.append(parent.getText(database)); parent = parent.getPossibleParent(database); } return result.toString(); } public static boolean acceptTime(String itemValidityPeriod, String requiredValidityPeriod) { if (Property.AIKAVALI_KAIKKI.equals(requiredValidityPeriod)) return true; TimeInterval itemInterval = TimeInterval.parse(itemValidityPeriod); TimeInterval requiredInterval = TimeInterval.parse(requiredValidityPeriod); return itemInterval.intersects(requiredInterval); } public static Set<String> getResponsibilityFields(Database database, Base b) { Set<String> result = new TreeSet<String>(); buildResponsibilityFieldsInternal(database, b, result); return result; } private static void buildResponsibilityFieldsInternal(Database database, Base b, Set<String> result) { Strategiakartta map = database.getMap(b); Base currentLevel = map.currentLevel(database); Relation modelRelation = Relation.find(database, Relation.RESPONSIBILITY_MODEL); ResponsibilityModel model = modelRelation.getPossibleRelationObject(database, currentLevel); if (model != null) { List<String> fields = model.getFields(); result.addAll(fields); } Base implemented = Utils.getPossibleImplemented(database, b); if (implemented != null) buildResponsibilityFieldsInternal(database, implemented, result); } public static Map<String, String> getResponsibilityMap(Database database, Base b) { TreeMap<String, String> result = new TreeMap<String, String>(); buildResponsibilityMapInternal(database, b, result); List<String> overrides = new ArrayList<String>(); for (Map.Entry<String, String> e : result.entrySet()) if ("-".equals(e.getValue())) overrides.add(e.getKey()); for (String override : overrides) result.remove(override); return result; } private static void buildResponsibilityMapInternal(Database database, Base b, Map<String, String> result) { Strategiakartta map = database.getMap(b); Base currentLevel = map.currentLevel(database); Relation modelRelation = Relation.find(database, Relation.RESPONSIBILITY_MODEL); ResponsibilityModel model = modelRelation.getPossibleRelationObject(database, currentLevel); if (model == null) return; Relation instanceRelation = Relation.find(database, Relation.RESPONSIBILITY_INSTANCE); ResponsibilityInstance instance = instanceRelation.getPossibleRelationObject(database, b); ResponsibilityInstance defaultInstance = instanceRelation.getPossibleRelationObject(database, map); Set<String> fields = getResponsibilityFields(database, b); for (String field : fields) { if (result.containsKey(field)) continue; String value = null; if (instance != null) { value = instance.getValue(field); if (value != null && !value.isEmpty()) result.put(field, value); } else if (defaultInstance != null) { value = defaultInstance.getValue(field); if (value != null && !value.isEmpty()) result.put(field, value); } } Base implemented = Utils.getPossibleImplemented(database, b); if (implemented != null) buildResponsibilityMapInternal(database, implemented, result); } }