001package de.deepamehta.workspaces.migrations;
002
003import de.deepamehta.core.Association;
004import de.deepamehta.core.DeepaMehtaObject;
005import de.deepamehta.core.RelatedTopic;
006import de.deepamehta.core.Topic;
007import de.deepamehta.core.model.ChildTopicsModel;
008import de.deepamehta.core.model.SimpleValue;
009import de.deepamehta.core.model.TopicModel;
010import de.deepamehta.core.service.Migration;
011
012import java.util.List;
013import java.util.logging.Logger;
014
015
016
017/**
018 * Runs only in UPDATE mode.
019 * <p>
020 * Part of DM 4.5
021 */
022public class Migration5 extends Migration {
023
024    // ------------------------------------------------------------------------------------------------------- Constants
025
026    // Note: copy in WorkspacesPlugin.java
027    private static final String PROP_WORKSPACE_ID = "dm4.workspaces.workspace_id";
028
029    // ---------------------------------------------------------------------------------------------- Instance Variables
030
031    private long objects = 0, initialized = 0, ambiguous = 0;;
032
033    private Logger logger = Logger.getLogger(getClass().getName());
034
035    // -------------------------------------------------------------------------------------------------- Public Methods
036
037    @Override
038    public void run() {
039        //
040        // 1) Initializes workspace properties
041        //
042        logger.info("########## Initializing workspace properties");
043        for (Topic topic : dm4.getAllTopics()) {
044            initWorkspaceProperty(topic);
045        }
046        for (Association assoc : dm4.getAllAssociations()) {
047            initWorkspaceProperty(assoc);
048        }
049        logger.info("########## Initializing workspace properties complete\n    Objects processed: " + objects +
050            "\n    initialized: " + initialized + "\n    ambiguous: " + ambiguous);
051        //
052        // 2) Changes cardinality of the workspace facet to "one".
053        //
054        dm4.getTopicType("dm4.workspaces.workspace_facet").getAssocDef("dm4.workspaces.workspace")
055            .setChildCardinalityUri("dm4.core.one");
056        //
057        // 3) Corrects URI of the "DeepaMehta" workspace: "de." -> "dm4."
058        //
059        dm4.getTopicByUri("de.workspaces.deepamehta").setUri("dm4.workspaces.deepamehta");
060        //
061        // 4) Sets the sharing mode of all workspaces to "Public".
062        //
063        for (Topic workspace : dm4.getTopicsByType("dm4.workspaces.workspace")) {
064            workspace.update(mf.newTopicModel(mf.newChildTopicsModel()
065                .putRef("dm4.workspaces.sharing_mode", "dm4.workspaces.public")
066            ));
067            // Note: instead of calling update(...) on the entire topic object we could update the child selectively:
068            //     workspace.getChildTopics().setRef("dm4.workspaces.sharing_mode", "dm4.workspaces.public")
069            // This would be much more concise. However in this case the topic will loose its label.
070            // ### TODO: fix that error in the labeling mechanism. ### TODO: check if already fixed
071        }
072    }
073
074    // ------------------------------------------------------------------------------------------------- Private Methods
075
076    private void initWorkspaceProperty(DeepaMehtaObject object) {
077        List<RelatedTopic> workspaces = object.getRelatedTopics("dm4.core.aggregation", "dm4.core.parent",
078            "dm4.core.child", "dm4.workspaces.workspace");
079        objects++;
080        switch (workspaces.size()) {
081        case 0:
082            break;
083        case 1:
084            long workspaceId = workspaces.get(0).getId();
085            object.setProperty(PROP_WORKSPACE_ID, workspaceId, false);      // addToIndex=false
086            initialized++;
087            break;
088        default:
089            // Note: user account related topics get proprietary workspace assignments.
090            // This is performed in Access Control migration #8 later on.
091            if (!isUserAccountRelated(object)) {
092                logger.warning("##### " + info(object) + " has ambiguous workspace assignments (" +
093                    workspaces.size() + ") -- This object will get NO workspace assignment " +
094                    "in DM 4.5 and will not be editable anymore");
095                ambiguous++;
096            }
097        }
098    }
099
100    private boolean isUserAccountRelated(DeepaMehtaObject object) {
101        String typeUri = object.getTypeUri();
102        return typeUri.equals("dm4.accesscontrol.user_account") ||
103            typeUri.equals("dm4.accesscontrol.username") ||
104            typeUri.equals("dm4.accesscontrol.password");
105    }
106
107    // ---
108
109    private String info(DeepaMehtaObject object) {
110        if (object instanceof Topic) {
111            return "topic " + object.getId() + " (typeUri=\"" + object.getTypeUri() + "\", value=\"" +
112                object.getSimpleValue() + "\", uri=\"" + object.getUri() + "\")";
113        } else if (object instanceof Association) {
114            return "association " + object.getId() + " (typeUri=\"" + object.getTypeUri() + "\")";
115        } else {
116            throw new RuntimeException("Unexpected object: " + object);
117        }
118    }
119}