001package systems.dmx.webclient.migrations; 002 003import systems.dmx.core.DMXType; 004import systems.dmx.core.Topic; 005import systems.dmx.core.ViewConfiguration; 006import systems.dmx.core.model.TopicModel; 007import systems.dmx.core.service.Migration; 008 009import java.util.List; 010import java.util.logging.Logger; 011 012 013 014/** 015 * Repairing types with missing "View Config" topic. 016 * Runs ALWAYS. 017 * <p> 018 * Note: while a "clean install" the Core types, and other types created before Webclient is activated, are repaired. 019 * While "update" all existing types are repaired, including the ones created by installed 3rd-party modules. 020 * <p> 021 * Part of DM 4.8.6 022 */ 023public class Migration3 extends Migration { 024 025 private long deepaMehtaWorkspaceId; 026 027 private int[][] count = new int[2][2]; 028 029 private Logger logger = Logger.getLogger(getClass().getName()); 030 031 @Override 032 public void run() { 033 // This migration creates View Config topics without any child topics. 034 // Now with the ValueIntegrator we can't create empty composites. 035 // See also addDefaultViewConfig() in WebclientPlugin.java 036 // ### TODO: rethink about this. 037 /* 038 initDMXWorkspaceId(); 039 // 040 logger.info("########## Repairing types with missing \"View Config\" topic (" + 041 (deepaMehtaWorkspaceId == -1 ? "clean install" : "update") + " detected)"); 042 // 043 repair(dmx.getAllTopicTypes(), 0); 044 repair(dmx.getAllAssociationTypes(), 1); 045 // 046 logger.info("########## Repairing types with missing \"View Config\" topic complete\n " + 047 "Topic types repaired: " + count[0][1] + "/" + count[0][0] + "\n " + 048 "Association types repaired: " + count[1][1] + "/" + count[1][0]); 049 */ 050 } 051 052 private void repair(List<? extends DMXType> types, int i) { 053 for (DMXType type : types) { 054 // Note: no View Config can be associated to the type "View Configuration" itself as this would cause an 055 // endless recursion while fetching that type. Fetching a type involves fetching its view config, that is 056 // all its view config topics, including their child topics. Fetching child topics is driven by the topic's 057 // type (its assoc defs), here: "View Configuration" -- the one we're fetching just now. 058 if (type.getUri().equals("dmx.webclient.view_config")) { 059 continue; 060 } 061 // 062 repair(type, i); 063 } 064 } 065 066 private void repair(DMXType type, int i) { 067 try { 068 ViewConfiguration viewConfig = type.getViewConfig(); 069 Topic configTopic = viewConfig.getConfigTopic("dmx.webclient.view_config"); 070 if (configTopic == null) { 071 // 1) create config topic 072 configTopic = viewConfig.addConfigTopic(mf.newTopicModel("dmx.webclient.view_config")); 073 // 074 // 2) assign workspace 075 // In case of a CLEAN_INSTALL the DMX workspace does not yet exist. The config topic gets its 076 // workspace assignment via type-introduction of the Workspaces module. The Workspaces module is 077 // activated *after* the Webclient module. 078 // In case of a UPDATE the DMX workspace exists already and we make the assignment here. 079 // Type-introduction of the Workspaces module will not perform as this module is installed already. 080 if (deepaMehtaWorkspaceId != -1 && isDMXStandardType(type)) { 081 dmx.getAccessControl().assignToWorkspace(configTopic, deepaMehtaWorkspaceId); 082 } 083 // 084 count[i][1]++; 085 } 086 count[i][0]++; 087 } catch (Exception e) { 088 throw new RuntimeException("Repairing type \"" + type.getUri() + "\" failed", e); 089 } 090 } 091 092 private void initDMXWorkspaceId() { 093 Topic ws = dmx.getTopicByUri("dmx.workspaces.deepamehta"); 094 deepaMehtaWorkspaceId = ws != null ? ws.getId() : -1; 095 } 096 097 // Copied from WorkspacePlugin.java 098 private boolean isDMXStandardType(DMXType type) { 099 return type.getUri().startsWith("dmx."); 100 } 101}