001    package de.deepamehta.plugins.workspaces.migrations;
002    
003    import de.deepamehta.core.Association;
004    import de.deepamehta.core.DeepaMehtaObject;
005    import de.deepamehta.core.RelatedTopic;
006    import de.deepamehta.core.Topic;
007    import de.deepamehta.core.model.ChildTopicsModel;
008    import de.deepamehta.core.model.SimpleValue;
009    import de.deepamehta.core.model.TopicModel;
010    import de.deepamehta.core.service.Migration;
011    import de.deepamehta.core.service.ResultList;
012    
013    import java.util.logging.Logger;
014    
015    
016    
017    /**
018     * Runs only in UPDATE mode.
019     * <p>
020     * Part of DM 4.5
021     */
022    public 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 : dms.getAllTopics()) {
044                initWorkspaceProperty(topic);
045            }
046            for (Association assoc : dms.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            dms.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            dms.getTopic("uri", new SimpleValue("de.workspaces.deepamehta")).setUri("dm4.workspaces.deepamehta");
060            //
061            // 4) Sets the sharing mode of all workspaces to "Public".
062            //
063            for (Topic workspace : dms.getTopics("dm4.workspaces.workspace", 0)) {
064                workspace.update(new TopicModel(null, new ChildTopicsModel()
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.
071            }
072        }
073    
074        // ------------------------------------------------------------------------------------------------- Private Methods
075    
076        private void initWorkspaceProperty(DeepaMehtaObject object) {
077            ResultList<RelatedTopic> workspaces = object.getRelatedTopics("dm4.core.aggregation",
078                "dm4.core.parent", "dm4.core.child", "dm4.workspaces.workspace", 0);
079            objects++;
080            switch (workspaces.getSize()) {
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.getSize() + ") -- 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    }