Обобщение редактора МПС

From IT SPb Academy

Jump to: navigation, search

Обобщение редактора МПС

Для поддержания редактора ОВЛ-инстансов предлагаю обобщить клетки для пропертей, реф.нодов и OWL property targets. Проперти, линки и овл-проперти являются случаем трёхместного отношения (SNode sourceNode, Object relationDeclaration, Object target). Для проперти это (SNode node, PropertyDeclaration propertyDeclaration, String propertyValue). Для линка это (SNode sourceNode, LinkDeclaration linkDeclaration, SNode targetNode). Для OWL-property это (SNode sourceInstance, SProperty owlProperty, Object target).

Необходим, также, достаточно общий плуггабельный механизм поиска редактора для данного нода.

Обобщение метаклеток

У нас будет CellModelWithRole extends EditorCellModel, который будут раcширять, из уже существующих, целлы ref.cell, ref.node, property, concept property и планируемая OWLproperty. CellModelWithRole - это обобщенная метаклетка, генерящая любые клетки, для которых есть отношение R(s,t), такое, что если редактируемый нод s, то они показывают нечто, завиясящее от t. /s - исходный нод, R - отношение, t - таргет/ Например, CellModel_Property показывает некую проперти нода. Отношение R - это декларация проперти, или имя проперти. t - это значение проперти. CellModel_RefNode показывает редактор для таргета некоторой ссылки. Отношение R - это декларация ссылки, или роль ссылки. t - это таргет ссылки. И т.п.

Эта метаклетка, CellModelWithRole, знает про исходный нод, про вид отношения, который назовём ролью, и про текст, который показывается при отсутствии таргета.

При генерации редактора, по имени класса конкретной метаклетки, который унаследован от CellModelWithRole, строится имя конкретного класса для целл провайдера, который расширяет CellProviderWithRole, и в сгенерённый код встраивается вызов метода createCell этого провайдера.

Сами целл-провайдеры будут написаны вручную.

Код будет выглядеть примерно так:

 //CellProviderWithRole
 public abstract class CellProviderWithRole extends AbstractCellProvider {
   protected String myNoTargetText;
   public CellProviderWithRole(SNode node) {
     super(node);
   }
   public abstract void setRole(Object role);
   public void setNoTargetText(String text) {
     myNoTargetText = text;
   }
 }


 //MANUALLY WRITTEN CELL PROVIDERS
 public class PropertyCellProvider extends CellProviderWithRole {
   String myPropertyName;
   public void setRole(Object role) {
     myPropertyName = role.toString();
   }
   public PropertyCellProvider(SNode node) {
     super(node);
   }
   public EditorCell createEditorCell(EditorContext context) {
     PropertyAccessor  propertyAccessor = new PropertyAccessor  (getSNode(), myPropertyName, false, true, context ) ;
     EditorCell_Property  editorCell = EditorCell_Property  . create ( context , propertyAccessor , getSNode()) ;
     editorCell.setDefaultText(myNoTargetText);
     return editorCell ;
   }
 }
 public class RefNodeCellProvider extends CellProviderWithRole {
   private String myRole;
   public void setRole(Object role) {
     myRole = role.toString();
   }
   public RefNodeCellProvider(SNode node) {
     super(node);
   }
    public EditorCell createEditorCell(EditorContext context) {
      SNode node = getSNode();
      SNode referencedNode = node . getReferent (myRole) ;
      LinkDeclaration  linkDeclaration = SModelUtil  . getLinkDeclaration ( node , myRole, context . getOperationContext (  ) . getScope (  ) ) ;
      SReference  reference = node . getReference (myRole) ;
      if ( reference != null && !( reference . isResolved (  ) ) ) {
        EditorCell_Error  noRefCell = EditorCell_Error  . create ( context , node , null ) ;
        noRefCell . setText ( BadReferenceTextProvider  . getBadReferenceText ( reference ) ) ;
        noRefCell . setAction ( EditorCellAction  . DELETE , new CellAction_Empty  (  ) ) ;
        noRefCell . putUserObject ( EditorCell  . ROLE , myRole);
        noRefCell . putUserObject ( EditorCell  . METAINFO_LINK_DECLARATION , linkDeclaration ) ;
        return noRefCell ;
      }
      if ( referencedNode == null ) {
        EditorCell_Constant  noRefCell = EditorCell_Constant  . create ( context , node , null , true ) ;
        noRefCell . setText (myNoTargetText);
        noRefCell . setDefaultText(myNoTargetText);
        noRefCell . setAction ( EditorCellAction  . DELETE , new CellAction_Empty  (  ) ) ;
        noRefCell . setSubstituteInfo ( new DefaultChildSubstituteInfo  ( node , linkDeclaration , context ) ) ;
        noRefCell . putUserObject ( EditorCell  . ROLE , myRole);
        noRefCell . putUserObject ( EditorCell  . METAINFO_LINK_DECLARATION , linkDeclaration ) ;
        return noRefCell ;
      }
      EditorCell  editorCell = context . createNodeCell ( referencedNode ) ;
      editorCell . putUserObject ( EditorCell  . ROLE , myRole ) ;
      editorCell . putUserObject ( EditorCell  . METAINFO_LINK_DECLARATION , linkDeclaration )  ;
      editorCell . setAction ( EditorCellAction  . DELETE , new CellAction_DeleteSmart  ( node , linkDeclaration , referencedNode ) ) ;
      editorCell . setAction ( EditorCellAction  . DELETE , new CellAction_DeleteReferenceToNode  ( node , myRole, referencedNode ) ) ;
      editorCell . setSubstituteInfo ( new DefaultChildSubstituteInfo  ( node , linkDeclaration , context ) ) ;
      return editorCell ;
    }
  }


 //GENERATED METHODS
 EditorCell createCellWithRole1(EditorContext context, SNode node) {
   CellProviderWithRole provider = new PropertyCellProvider(node);
   provider.setRole("name");
   provider.setNoTargetText("<no name>");
   EditorCell editorCell = provider.createEditorCell(context);
   editorCell.setSelectable(true);
   editorCell.setDrawBorder(false);
   editorCell.setDrawBrackets(false);
   editorCell.setBracketsColor(Color.black);
   editorCell.setFontType(MPSFonts.BOLD);
   editorCell.setFontSize(25);
   editorCell.setLayoutConstraint("");
   return editorCell;
 }
 EditorCell createCellWithRole3(EditorContext context, SNode node) {
   CellProviderWithRole provider = new RefNodeCellProvider(node);
   provider.setRole("extends");
   provider.setNoTargetText("<no class>");
   EditorCell editorCell = provider.createEditorCell(context);
   editorCell.setSelectable(true);
   editorCell.setDrawBorder(false);
   editorCell.setDrawBrackets(false);
   editorCell.setBracketsColor(Color.black);
   editorCell.setFontType(MPSFonts.BOLD);
   editorCell.setFontSize(25);
   editorCell.setLayoutConstraint("");
   return editorCell;
 }

Поиск редактора не по концепту, а по "обобщающей сущности"

Хочется редактировать инстансы разных ОВЛ-классов различным образом, то есть именно как инстансов ОВЛ-класса, а не как инстансов концепта OWLInstance или как там его назвать. То есть для нодов типа OWLInstance обобщающей сущностью является не их ConceptDeclaration, а соответственный инстанс концепта OWLClass. Соответственно мы имеем, в простом случае, один редактор на один ОВЛ-класс, а не один редактор на все OWLInstances. Сейчас я сделал так, что в зависимости от языка нода ищется соответственный IGeneralizingEntityEditorFinder, который в свою очередь осуществляет поиск подходящего редактора для данного нода. Для языка работы с ОВЛ нам надо будет создавать свой файндер, который будет искать не по концепту, а по ОВЛ-классу.

Views