package se.cambio.cds.gdl.editor.controller; import difflib.Delta; import difflib.DiffUtils; import difflib.Patch; import org.apache.commons.lang.StringUtils; import org.apache.log4j.Logger; import org.openehr.rm.datatypes.text.CodePhrase; import se.cambio.cds.controller.guide.GuideUtil; import se.cambio.cds.formgen.controller.FormGeneratorController; import se.cambio.cds.formgen.view.dialog.CDSFormGenDialog; import se.cambio.cds.gdl.editor.controller.interfaces.EditorController; import se.cambio.cds.gdl.editor.controller.sw.CheckGuideSW; import se.cambio.cds.gdl.editor.controller.sw.CompileGuideSW; import se.cambio.cds.gdl.editor.controller.sw.SaveGuideOnFileRSW; import se.cambio.cds.gdl.editor.util.DefinitionDependencyChecker; import se.cambio.cds.gdl.editor.util.GDLEditorLanguageManager; import se.cambio.cds.gdl.editor.view.dialog.DialogNameInsert; import se.cambio.cds.gdl.editor.view.panels.GDLEditorMainPanel; import se.cambio.cds.gdl.editor.view.panels.GDLPanel; import se.cambio.cds.gdl.model.*; import se.cambio.cds.gdl.model.expression.AssignmentExpression; import se.cambio.cds.gdl.model.expression.ExpressionItem; import se.cambio.cds.gdl.model.readable.ReadableGuide; import se.cambio.cds.gdl.model.readable.rule.ReadableRule; import se.cambio.cds.gdl.model.readable.rule.RuleLineCollection; import se.cambio.cds.gdl.model.readable.rule.lines.ArchetypeElementInstantiationRuleLine; import se.cambio.cds.gdl.model.readable.rule.lines.ArchetypeInstantiationRuleLine; import se.cambio.cds.gdl.model.readable.rule.lines.AssignmentExpressionRuleLine; import se.cambio.cds.gdl.model.readable.rule.lines.ExpressionRuleLine; import se.cambio.cds.gdl.model.readable.rule.lines.RuleLine; import se.cambio.cds.gdl.model.readable.rule.lines.WithElementPredicateAttributeDefinitionRuleLine; import se.cambio.cds.gdl.model.readable.rule.lines.WithElementPredicateExistsDefinitionRuleLine; import se.cambio.cds.gdl.model.readable.rule.lines.WithElementPredicateExpressionDefinitionRuleLine; import se.cambio.cds.gdl.model.readable.rule.lines.WithElementPredicateFunctionDefinitionRuleLine; import se.cambio.cds.gdl.model.readable.rule.lines.elements.RuleLineElementWithValue; import se.cambio.cds.model.instance.ArchetypeReference; import se.cambio.cds.util.GuideImporter; import se.cambio.cds.view.swing.panel.interfaces.RefreshablePanel; import se.cambio.cm.model.archetype.vo.ArchetypeElementVO; import se.cambio.cm.model.guide.dto.GuideDTO; import se.cambio.cm.model.guide.dto.GuideDTOBuilder; import se.cambio.cm.model.util.CMTypeFormat; import se.cambio.openehr.controller.session.data.ArchetypeManager; import se.cambio.openehr.util.ExceptionHandler; import se.cambio.openehr.util.IOUtils; import se.cambio.openehr.util.UserConfigurationManager; import se.cambio.openehr.util.exceptions.InstanceNotFoundException; import se.cambio.openehr.util.exceptions.InternalErrorException; import se.cambio.openehr.view.dialogs.DialogLongMessageNotice; import se.cambio.openehr.view.dialogs.DialogLongMessageNotice.MessageType; import se.cambio.openehr.view.dialogs.InfoDialog; import se.cambio.openehr.view.util.ImportUtils; import javax.swing.*; import javax.swing.filechooser.FileNameExtensionFilter; import java.awt.*; import java.io.BufferedOutputStream; import java.io.File; import java.io.FileOutputStream; import java.io.InputStream; import java.io.ObjectOutputStream; import java.util.*; import java.util.List; public class GDLEditor implements EditorController<Guide>{ private static String UNKOWN_GUIDE_ID = "unknown"; private GDLEditorMainPanel _gdlEditorMainPanel = null; private ResourceDescription _resourceDescription = null; private GuideOntology _guideOntology = null; private ReadableGuide _readableGuide = null; private ReadableRule _ruleAtEdit = null; private Map<String, TermDefinition> _termDefinitions = null; private Map<String, TermBinding> _termBindings = null; private Language _language; private Map<String, String> _originalAuthor; private List<String> _otherContributors; private Map<String, ResourceDescriptionItem> _details; private Map<String, String> _otherDetails; private InfoDialog _infoDialog; private String _idGuide = UNKOWN_GUIDE_ID; private String _conceptGTCode; private String _currentGuideLanguageCode = null; private String _originalGuide = null; private RefreshablePanel _lastRefreshedPanel = null; private static String LANGUAGE_TERMINOLOGY = "ISO_639-1"; private static String GT_HEADER = "gt";//TODO Link to model private static String GDL_VERSION = "0.1"; private static String DRAFT = "Author draft"; public GDLEditor() { } public GDLEditor(Guide guide) { if (guide==null) { guide = new Guide(); } setEntity(guide); } public void init() { EditorManager.getActiveEditorViewer().setContent(getEditorPanel()); EditorManager.getMainMenuBar().refreshLanguageMenu(); } public String getTitle() { return getAppName()+" - "+getConceptName(); } private String getConceptName() { String conceptName = getGTName(getConceptGTCode()); if (conceptName == null) { conceptName = GDLEditorLanguageManager.getMessage("Guide"); } return conceptName; } private String getAppName() { return GDLEditorLanguageManager.getMessage("GDLEditor"); } public boolean checkRuleLineDelete(RuleLine ruleLine) { if (ruleLine instanceof ArchetypeInstantiationRuleLine) { return checkArchetypeReferenceRemoval((ArchetypeInstantiationRuleLine) ruleLine); } else if (ruleLine instanceof ArchetypeElementInstantiationRuleLine) { return checkArchetypeReferenceRemoval((ArchetypeElementInstantiationRuleLine) ruleLine); } else { return true; } } private boolean checkArchetypeReferenceRemoval(ArchetypeInstantiationRuleLine airl) { if (DefinitionDependencyChecker.isBeingUsed(airl, this)) { JOptionPane.showMessageDialog( EditorManager.getActiveEditorWindow(), GDLEditorLanguageManager.getMessage("ReferenceBeingUsedMsg"), GDLEditorLanguageManager.getMessage("ReferenceBeingUsedTitle"), JOptionPane.WARNING_MESSAGE); return false; } else { return true; } } private boolean checkArchetypeReferenceRemoval( ArchetypeElementInstantiationRuleLine aeirl) { if (DefinitionDependencyChecker.isBeingUsed(aeirl, this)) { JOptionPane.showMessageDialog( EditorManager.getActiveEditorWindow(), GDLEditorLanguageManager.getMessage("ReferenceBeingUsedMsg"), GDLEditorLanguageManager.getMessage("ReferenceBeingUsedTitle"), JOptionPane.WARNING_MESSAGE); return false; } else { return true; } } public GDLEditorMainPanel getEditorPanel() { if (_gdlEditorMainPanel == null) { _gdlEditorMainPanel = new GDLEditorMainPanel(this); } return _gdlEditorMainPanel; } public void saveAs(){ _gdlEditorMainPanel.requestFocus(); runIfOkWithEditorState(new Runnable() { @Override public void run() { new SaveGuideOnFileRSW(null).execute(); } }); } @Override public void entitySaved() { updateOriginal(); } public void save() { _gdlEditorMainPanel.requestFocus(); runIfOkWithEditorState(new Runnable() { @Override public void run() { new SaveGuideOnFileRSW(EditorManager.getLastFileLoaded()).execute(); } }); } public void generateForm(){ _gdlEditorMainPanel.requestFocus(); Runnable runnable = new Runnable() { @Override public void run() { if (!hasActiveRules()){ JOptionPane.showMessageDialog(EditorManager.getActiveEditorWindow(), GDLEditorLanguageManager.getMessage("PleaseInsertRulesBeforeGeneratingForm"), GDLEditorLanguageManager.getMessage("GenerateForm"), JOptionPane.WARNING_MESSAGE); return; } String gdlGuide = getSerializedEntity(); if (gdlGuide!=null){ CompileGuideSW sw = new CompileGuideSW(){ protected void done() { getController().compilationFinished(getErrorMsg()); if (getErrorMsg()==null){ try { generateDialogForm(getCompiledGuide(), getGuide()); } catch (InternalErrorException e) { ExceptionHandler.handle(e); } } } }; sw.execute(); setBusy(GDLEditorLanguageManager.getMessage("Compiling") + "..."); } } }; runIfOkWithEditorState(runnable); } private void generateDialogForm(byte[] compiledGuide, Guide guide) throws InternalErrorException { EditorController controller = EditorManager.getActiveEditorController(); String gdlGuide = controller.getSerializedEntity(); if (compiledGuide!=null && gdlGuide!=null){ GuideDTO guideDTO = new GuideDTOBuilder() .setId(controller.getEntityId()) .setFormat(CMTypeFormat.GDL_FORMAT.getFormat()) .setSource(gdlGuide) .setGuideObject(IOUtils.getBytes(guide)) .setCompiledGuide(compiledGuide) .setLastUpdate(Calendar.getInstance().getTime()) .createGuideDTO(); FormGeneratorController formGenerator = new FormGeneratorController(guideDTO, controller.getCurrentLanguageCode()); Date date = UserConfigurationManager.getCustomDate(); if (date!=null){ Calendar cal = Calendar.getInstance(); cal.setTime(date); formGenerator.setCurrentDate(cal); } CDSFormGenDialog dialog = new CDSFormGenDialog(EditorManager.getActiveEditorWindow()); dialog.setFormGeneratorController(formGenerator); //dialog.addWindowListener(new CloseAction()); dialog.setVisible(true); } } public void compile() { new CompileGuideSW().execute(); setBusy(GDLEditorLanguageManager.getMessage("Compiling")); } public void compilationFinished(String msg) { setFree(); if (msg != null) { JOptionPane.showMessageDialog( EditorManager.getActiveEditorWindow(), msg, GDLEditorLanguageManager.getMessage("Error"), JOptionPane.ERROR_MESSAGE); } } public ReadableRule createNewRule() { _ruleAtEdit = null; DialogNameInsert dialog = new DialogNameInsert( EditorManager.getActiveEditorWindow(), GDLEditorLanguageManager.getMessage("RuleName"), ""); if (dialog.getAnswer()) { _ruleAtEdit = new ReadableRule(getCurrentTermDefinition(), createNextLocalCode(), _readableGuide); setGTName(_ruleAtEdit.getGTCode(), dialog.getValue()); getRenderableRules().put(_ruleAtEdit.getGTCode(), _ruleAtEdit); } return _ruleAtEdit; } public void ruleEdit(ReadableRule rule) { _ruleAtEdit = rule; getEditorPanel().loadRuleView(rule); } public LinkedHashMap<String, ReadableRule> getRenderableRules() { return getReadableGuide().getReadableRules(); } public boolean hasActiveRules() { boolean hasActiveRules = false; Iterator<ReadableRule> i = getRenderableRules().values().iterator(); while (i.hasNext() && !hasActiveRules) { hasActiveRules = !i.next().isCommented(); } return hasActiveRules; } public void changeCommentRule(ReadableRule rule, boolean comment) { rule.setCommented(comment); } public void goBackToGuide() { getEditorPanel().loadGuideView(); } public ResourceDescription getResourceDescription() { if (_resourceDescription == null) { _resourceDescription = new ResourceDescription(); _resourceDescription.setLifecycleState(DRAFT); initResourceDescription(); } return _resourceDescription; } private void initResourceDescription() { getOriginalAuthor(); getOtherContributors(); getResourceDescriptionItem(getCurrentLanguageCode()); getOtherDetails(); getKeywords(); } public Map<String, String> getOriginalAuthor() { if (_originalAuthor == null) { _originalAuthor = new HashMap<String, String>(); getResourceDescription().setOriginalAuthor(_originalAuthor); } return _originalAuthor; } public List<String> getOtherContributors() { if (_otherContributors == null) { _otherContributors = new ArrayList<String>(); getResourceDescription().setOtherContributors(_otherContributors); } return _otherContributors; } public Map<String, ResourceDescriptionItem> getDetails() { if (_details == null) { _details = new HashMap<String, ResourceDescriptionItem>(); getResourceDescription().setDetails(_details); } return _details; } private ResourceDescriptionItem getResourceDescriptionItem(String lang){ ResourceDescriptionItem resourceDescriptionItem = getDetails().get(lang); if (resourceDescriptionItem==null){ resourceDescriptionItem = new ResourceDescriptionItem(); getDetails().put(lang, resourceDescriptionItem); } return resourceDescriptionItem; } public Map<String, String> getOtherDetails() { if (_otherDetails == null) { _otherDetails = new HashMap<String, String>(); getResourceDescription().setOtherDetails(_otherDetails); } return _otherDetails; } public ResourceDescriptionItem getResourceDescriptionItem() { ResourceDescriptionItem resourceDescriptionItem = getResourceDescription().getDetails().get(getCurrentLanguageCode()); if (resourceDescriptionItem == null) { resourceDescriptionItem = new ResourceDescriptionItem(); getResourceDescription().getDetails().put( getCurrentLanguageCode(), resourceDescriptionItem); } return resourceDescriptionItem; } public List<String> getKeywords() { List<String> keywords = getResourceDescriptionItem().getKeywords(); if (keywords == null) { keywords = new ArrayList<String>(); getResourceDescriptionItem().setKeywords(keywords); } return keywords; } public RuleLineCollection getPreconditionRuleLines() { return getReadableGuide().getPreconditionRuleLines(); } public RuleLineCollection getDefinitionRuleLines() { return getReadableGuide().getDefinitionRuleLines(); } public ReadableGuide getReadableGuide() { if (_readableGuide == null) { _readableGuide = new ReadableGuide(getCurrentTermDefinition(), ArchetypeManager.getInstance()); } return _readableGuide; } public RuleLineCollection getConditionRuleLines() { return _ruleAtEdit.getConditionRuleLines(); } public RuleLineCollection getActionsRuleLines() { return _ruleAtEdit.getActionRuleLines(); } public void editRuleElement(RuleLineElementWithValue<?> ruleLineElementWithValue) { try { RuleElementEditor.edit(ruleLineElementWithValue); } catch (InternalErrorException e) { ExceptionHandler.handle(e); } catch (InstanceNotFoundException e) { ExceptionHandler.handle(e); } } public void runIfOKToExit(final Runnable pendingRunnable) { Runnable runnable = new Runnable() { @Override public void run() { if (isModified()) { int response = JOptionPane.showConfirmDialog( EditorManager.getActiveEditorWindow(), GDLEditorLanguageManager.getMessage("SavingChangesMessage"), GDLEditorLanguageManager.getMessage("SavingChanges"), JOptionPane.INFORMATION_MESSAGE); if (response == JOptionPane.YES_OPTION) { SaveGuideOnFileRSW rsw = new SaveGuideOnFileRSW( EditorManager.getLastFileLoaded()) { protected void done() { super.done(); if (getFile() != null) { pendingRunnable.run(); } } }; rsw.execute(); }else if (response == JOptionPane.NO_OPTION) { pendingRunnable.run(); } } else { pendingRunnable.run(); } } }; runIfOkWithEditorState(runnable); } private GuideOntology getGuideOntology(){ if (_guideOntology==null){ _guideOntology = new GuideOntology(); _guideOntology.setTermDefinitions(getTermDefinitions()); _guideOntology.setTermBindings(getTermBindings()); } return _guideOntology; } private Map<String, TermDefinition> getTermDefinitions() { if (_termDefinitions == null) { _termDefinitions = new HashMap<String, TermDefinition>(); String lang = getOriginalLanguageCode(); TermDefinition td = new TermDefinition(); td.setTerms(new HashMap<String, Term>()); _termDefinitions.put(lang, td); } return _termDefinitions; } public Map<String, TermBinding> getTermBindings() { if (_termBindings == null) { _termBindings = new HashMap<String, TermBinding>(); } return _termBindings; } public Collection<String> getSupportedLanguageCodes() { return getTermDefinitions().keySet(); } private TermDefinition getTermDefinition(String language) { TermDefinition termDefinition = getTermDefinitions().get(language); if (termDefinition == null) { termDefinition = new TermDefinition(); termDefinition.setId(language); termDefinition.setTerms(new HashMap<String, Term>()); getTermDefinitions().put(language, termDefinition); } return termDefinition; } public TermDefinition getCurrentTermDefinition() { return getTermDefinition(getCurrentLanguageCode()); } private Language getLanguage() { if (_language == null) { _language = new Language(); } return _language; } public String getCurrentLanguageCode() { if (_currentGuideLanguageCode == null) { String editorLanguage = UserConfigurationManager.getLanguage(); if (getSupportedLanguageCodes().contains(editorLanguage)) { _currentGuideLanguageCode = editorLanguage; } else { _currentGuideLanguageCode = getOriginalLanguageCode(); } } return _currentGuideLanguageCode; } public String getOriginalLanguageCode() { CodePhrase originalLanuageCodePhrase = getLanguage().getOriginalLanguage(); if (originalLanuageCodePhrase==null){ originalLanuageCodePhrase = new CodePhrase( LANGUAGE_TERMINOLOGY, UserConfigurationManager.getLanguage()); getLanguage().setOriginalLanguage(originalLanuageCodePhrase); } return getLanguage().getOriginalLanguage().getCodeString(); } public void setCurrentGuideLanguageCode(String languageCode) { _currentGuideLanguageCode = languageCode; } public String createNextLocalCode() { return createNextGTCode(true); } public String createNextGTCode(boolean generateTerm) { String gtCode = generateNextGTCode(generateTerm); if (generateTerm){ getTerm(gtCode).setText(null); getTerm(gtCode).setDescription(null); } return gtCode; } private String generateNextGTCode(boolean generateTerm) { String nextGTCode = GT_HEADER + StringUtils.leftPad("" + (getNextTermNumber()), 4, "0"); if (generateTerm){ // Generate codes for all terminologies for (String langCode : getTermDefinitions().keySet()) { getTerm(langCode, nextGTCode); } } return nextGTCode; } private int getNextTermNumber(){ TermDefinition termDefinition = getTermDefinition(getLanguage() .getOriginalLanguage().getCodeString()); int termCount = 0; if (termDefinition.getTerms() != null) { Set<String> gtCodes = new HashSet<String>(); gtCodes.addAll(termDefinition.getTerms().keySet()); for (RuleLine ruleLine: getDefinitionRuleLines().getRuleLines()){ if (ruleLine instanceof ArchetypeInstantiationRuleLine){ gtCodes.add(((ArchetypeInstantiationRuleLine)ruleLine).getGTCode()); } } for (String gtCode : gtCodes) { try { int codeNum = Integer.parseInt(gtCode.substring(2)); if (codeNum > termCount) { termCount = codeNum; } } catch (Exception e) { Logger.getLogger(this.getClass()).warn("Unable to parse code '" + gtCode + "'"); } } } return ++termCount; } public String getConceptGTCode() { if (_conceptGTCode == null) { _conceptGTCode = createNextLocalCode(); } return _conceptGTCode; } public Map<String, Term> getCurrentTermsMap() { return getTermsMap(getCurrentLanguageCode()); } @Override public Collection<String> getUsedCodes() { Collection<String> gtCodesUsed = new ArrayList<String>(); gtCodesUsed.addAll(getGTCodesUsedInDefinitions()); gtCodesUsed.addAll(getGTCodesUsedInBindings()); return gtCodesUsed; } public Map<String, Term> getTermsMap(String langCode) { Map<String, Term> terms = getTermDefinition(langCode).getTerms(); if (terms == null) { terms = new HashMap<String, Term>(); getTermDefinition(langCode).setTerms(terms); } return terms; } public Term getTerm(String gtCode) { return getTerm(getCurrentLanguageCode(), gtCode); } public Term getTerm(String langCode, String gtCode) { Term term = getCurrentTermsMap().get(gtCode); if (term == null) { Term originalTerm = getTermDefinition(getOriginalLanguageCode()) .getTerms().get(gtCode); term = getTermToDifferentLanguage(gtCode, originalTerm, getOriginalLanguageCode()); getTermsMap(langCode).put(gtCode, term); } return getTermsMap(langCode).get(gtCode); } private static Term getTermToDifferentLanguage(String gtCode, Term originalTerm, String originalLanguage) { Term newTerm = new Term(); newTerm.setId(gtCode); String text = null; String description = null; if (originalTerm != null && originalTerm.getText() != null && !originalTerm.getText().isEmpty()) { text = "*" + originalTerm.getText() + " (" + originalLanguage + ")"; } if (originalTerm != null && originalTerm.getDescription() != null && !originalTerm.getDescription().isEmpty()) { description = "*" + originalTerm.getDescription() + " (" + originalLanguage + ")"; } newTerm.setText(text); newTerm.setDescription(description); return newTerm; } public Term getConceptTerm() { return getCurrentTermsMap().get(getConceptGTCode()); } public String getGTName(String gtCode) { return getTerm(gtCode).getText(); } public void setGTName(String gtCode, String text) { Term term = getTerm(gtCode); term.setText(text); } public String getGTDescription(String gtCode) { return getTerm(gtCode).getDescription(); } private Guide constructCurrentGuide() throws IllegalStateException { GuideDefinition guideDefinition = new GuideDefinition(); // Insert definition for (RuleLine ruleLine : getDefinitionRuleLines().getRuleLines()) { if (!ruleLine.isCommented()) { if (ruleLine instanceof ArchetypeInstantiationRuleLine) { ArchetypeInstantiationRuleLine airl = (ArchetypeInstantiationRuleLine) ruleLine; ArchetypeReference ar = airl.getArchetypeReference(); if (ar != null) { Map<String, ElementBinding> elementMap = new HashMap<String, ElementBinding>(); List<ExpressionItem> predicateStatements = new ArrayList<ExpressionItem>(); for (RuleLine ruleLineAux : airl.getChildrenRuleLines().getRuleLines()) { if (!ruleLineAux.isCommented()) { if (ruleLineAux instanceof ArchetypeElementInstantiationRuleLine) { ArchetypeElementInstantiationRuleLine aeirl = (ArchetypeElementInstantiationRuleLine) ruleLineAux; ArchetypeElementVO archetypeElementVO = aeirl .getArchetypeElementRuleLineDefinitionElement() .getValue(); String elementGTCode = aeirl.getGTCode(); if (archetypeElementVO != null) { ElementBinding element = new ElementBinding( elementGTCode, archetypeElementVO.getPath()); elementMap.put(elementGTCode, element); } } else if (ruleLineAux instanceof WithElementPredicateAttributeDefinitionRuleLine) { WithElementPredicateAttributeDefinitionRuleLine wepadrl = (WithElementPredicateAttributeDefinitionRuleLine) ruleLineAux; predicateStatements.add(wepadrl.toExpressionItem()); } else if (ruleLineAux instanceof WithElementPredicateExpressionDefinitionRuleLine) { WithElementPredicateExpressionDefinitionRuleLine wepedrl = (WithElementPredicateExpressionDefinitionRuleLine) ruleLineAux; predicateStatements.add(wepedrl.toExpressionItem()); } else if (ruleLineAux instanceof WithElementPredicateFunctionDefinitionRuleLine) { WithElementPredicateFunctionDefinitionRuleLine wepfdrl = (WithElementPredicateFunctionDefinitionRuleLine) ruleLineAux; predicateStatements.add(wepfdrl.toExpressionItem()); } else if (ruleLineAux instanceof WithElementPredicateExistsDefinitionRuleLine) { WithElementPredicateExistsDefinitionRuleLine wepedrl = (WithElementPredicateExistsDefinitionRuleLine) ruleLineAux; predicateStatements.add(wepedrl.toExpressionItem()); } } } ArchetypeBinding archetypeBinding = new ArchetypeBinding(); archetypeBinding.setArchetypeId(ar.getIdArchetype()); archetypeBinding.setDomain(ar.getIdDomain()); archetypeBinding.setTemplateId(ar.getIdTemplate()); archetypeBinding.setElements(elementMap); archetypeBinding.setPredicateStatements(predicateStatements); archetypeBinding.setId(airl.getGTCode()); guideDefinition.getArchetypeBindings().put(archetypeBinding.getId(), archetypeBinding); } } } } // Insert preconditions List<ExpressionItem> preConditions = convertToExpressionItems(getPreconditionRuleLines().getRuleLines()); guideDefinition.setPreConditionExpressions(preConditions); // Insert rules int priority = getRenderableRules().size(); for (ReadableRule renderableRule : getRenderableRules().values()) { if (!renderableRule.isCommented()) { String gtCode = renderableRule.getGTCode(); Rule rule = new Rule(); rule.setId(gtCode); guideDefinition.getRules().put(gtCode, rule); rule.setWhenStatements(convertToExpressionItems(renderableRule.getConditionRuleLines().getRuleLines())); rule.setThenStatements(convertToAssigmentExpressionItems(renderableRule.getActionRuleLines().getRuleLines())); rule.setPriority(priority--); } } Guide guide = new Guide(); guide.setId(getEntityId()); guide.setGdlVersion(GDL_VERSION); guide.setLanguage(getLanguage()); guide.setConcept(getConceptGTCode()); guide.setDescription(getResourceDescription()); guide.setDefinition(guideDefinition); guide.setOntology(getGuideOntology()); if (!getTermDefinitions().isEmpty()) { cleanRedundantTerms(); } if (!getTermBindings().isEmpty()) { cleanRedundantTerms(); updateInvalidData(); } return guide; } public Guide getEntity() { try { return constructCurrentGuide(); } catch (IllegalStateException e) { DialogLongMessageNotice dialog = new DialogLongMessageNotice( EditorManager.getActiveEditorWindow(), GDLEditorLanguageManager.getMessage("ErrorSerializingGuideT"), GDLEditorLanguageManager.getMessage("ErrorSerializingGuide"), e.getMessage(), MessageType.ERROR); dialog.setVisible(true); return null; } } private void updateInvalidData() { Set<String> codesStringSet = getTermBindings().keySet(); for (String codeString : codesStringSet) { if (getTermBindings().get(codeString).getBindings() == null) { getTermBindings().get(codeString).setBindings( new HashMap<String, Binding>()); } } } public void updateOriginal() { _originalGuide = getSerializedEntity(); } public String getSerializedEntity() { Guide guide = getEntity(); if (guide != null) { return serializeGuide(guide); } else { return null; } } @Override public Guide parseEntity(InputStream is) { return parseGuide(is); } @Override public String getEntityName() { return GDLEditorLanguageManager.getMessage("Guide"); } @Override public Collection<String> getSupportedEntityExtensions() { return Collections.singleton("gdl"); } public static String serializeGuide(Guide guide) { try { return GuideUtil.serializeGuide(guide); } catch (Exception e) { e.printStackTrace(); DialogLongMessageNotice dialog = new DialogLongMessageNotice( EditorManager.getActiveEditorWindow(), GDLEditorLanguageManager.getMessage("ErrorSerializingGuideT"), GDLEditorLanguageManager.getMessage("ErrorSerializingGuide"), e.getMessage(), MessageType.ERROR); dialog.setVisible(true); return null; } } public static Guide parseGuide(InputStream input) { try { return GuideUtil.parseGuide(input); } catch (Exception e) { e.printStackTrace(); DialogLongMessageNotice dialog = new DialogLongMessageNotice( EditorManager.getActiveEditorWindow(), GDLEditorLanguageManager.getMessage("ErrorParsingGuideT"), GDLEditorLanguageManager.getMessage("ErrorParsingGuide"), e.getMessage(), MessageType.ERROR); dialog.setVisible(true); return null; } } public List<ExpressionItem> convertToExpressionItems( Collection<RuleLine> ruleLines) { List<ExpressionItem> list = new ArrayList<ExpressionItem>(); for (RuleLine ruleLine : ruleLines) { if (!ruleLine.isCommented()) { ExpressionItem ei = ((ExpressionRuleLine) ruleLine).toExpressionItem(); if (ei != null) { list.add(ei); } } } return list; } public List<AssignmentExpression> convertToAssigmentExpressionItems( Collection<RuleLine> ruleLines) { List<AssignmentExpression> list = new ArrayList<AssignmentExpression>(); for (RuleLine ruleLine : ruleLines) { if (!ruleLine.isCommented()) { AssignmentExpression assignmentExpression = ((AssignmentExpressionRuleLine) ruleLine).toAssignmentExpression(); list.add(assignmentExpression); } } return list; } @Override public String getEntityId() { return _idGuide; } @Override public void setEntityId(String idGuide) { _idGuide = idGuide; } public void changeLanguage(String language) { Guide guide = getEntity(); if (guide != null) { TermDefinition originalTermDefinition = getTermDefinitions().get(getOriginalLanguageCode()); TermDefinition termDefinition = getTermDefinition(language); for (String gtCode : originalTermDefinition.getTerms().keySet()) { Term term = termDefinition.getTerms().get(gtCode); if (term==null || term.getText()==null){ term = getTermToDifferentLanguage( gtCode, originalTermDefinition.getTerms().get(gtCode), getOriginalLanguageCode()); termDefinition.getTerms().put(gtCode, term); } if (term==null || term.getText()==null){ term = getTermToDifferentLanguage( gtCode, getTermDefinition(_currentGuideLanguageCode).getTerms().get(gtCode), _currentGuideLanguageCode); termDefinition.getTerms().put(gtCode, term); } } _currentGuideLanguageCode = language; getResourceDescriptionItem(language); EditorManager.getMainMenuBar().refreshLanguageMenu(); refreshCurrentTab(); } } public void refreshCurrentTab() { getEditorPanel().refresh(); } public void tabChanged(Component comp){ final RefreshablePanel refreshablePanel; if (comp instanceof RefreshablePanel && comp!=_lastRefreshedPanel){ refreshablePanel = (RefreshablePanel)comp; }else{ refreshablePanel = null; } runIfOkWithEditorState(comp, new Runnable() { @Override public void run() { SwingUtilities.invokeLater(new Runnable() { @Override public void run() { refreshPanel(refreshablePanel); } }); } }); } private void refreshPanel(RefreshablePanel refreshablePanel){ if (refreshablePanel!=null){ refreshablePanel.refresh(); _lastRefreshedPanel = refreshablePanel; } } private void runIfOkWithEditorState(Runnable pendingRunnable){ Component comp = null; try{ comp = getEditorPanel().getGuidePanel().getGuideEditorTabPane().getSelectedComponent(); }catch (Exception e){ ExceptionHandler.handle(e); //TODO } runIfOkWithEditorState(comp, pendingRunnable); } private void runIfOkWithEditorState(Component currentPanel, Runnable pendingRunnable){ if (_lastRefreshedPanel instanceof GDLPanel/* && _lastRefreshedPanel!=currentPanel*/){ //Take care of possible changes made GDLPanel gdlPanel = (GDLPanel)_lastRefreshedPanel; String guideStr = gdlPanel.getGuideStr(); new CheckGuideSW(this, guideStr, pendingRunnable).execute(); }else if (currentPanel instanceof GDLPanel){ try { String guideStr = null; Guide guide = getEntity(); if (guide!=null){ guideStr = serializeGuide(guide); } if (guideStr!=null){ new CheckGuideSW(this, guideStr, pendingRunnable).execute(); }else{ loadLastTab(); } } catch (Exception e) { //Errors found serializing/parsing/compiling guide, so we do not load the source view loadLastTab(); } }else{ pendingRunnable.run(); } } public void gdlEditingChecked(Guide guide, boolean checkOk, String msg, Runnable pendingRunnable){ if (checkOk && guide!=null){ String auxOriginalGuide = _originalGuide; setEntity(guide); _originalGuide = auxOriginalGuide; if (pendingRunnable!=null){ pendingRunnable.run(); } }else{ DialogLongMessageNotice dialog = new DialogLongMessageNotice( EditorManager.getActiveEditorWindow(), GDLEditorLanguageManager.getMessage("IgnoreGDLSourceChangesTitle"), GDLEditorLanguageManager.getMessage("IgnoreGDLSourceChanges"), msg, MessageType.WARNING_WITH_CANCEL ); dialog.setVisible(true); if (dialog.getAnswer()){ if (pendingRunnable!=null){ pendingRunnable.run(); } }else{ loadLastTab(); } } } private void loadLastTab(){ Component component = (Component)_lastRefreshedPanel; _gdlEditorMainPanel.getGuidePanel().getGuideEditorTabPane().setSelectedComponent(component); } private void initGuideVars(){ _idGuide = UNKOWN_GUIDE_ID; _resourceDescription = null; _originalAuthor = null; _details = null; _otherContributors = null; _otherDetails = null; _language = null; _conceptGTCode = null; _guideOntology = null; _termDefinitions = null; _termBindings = null; _readableGuide = null; _ruleAtEdit = null; } public void setEntity(Guide guide) { try { checkGuideArchetypesAndTemplates(guide); } catch (InternalErrorException e) { ExceptionHandler.handle(e); } catch (InstanceNotFoundException e) { ExceptionHandler.handle(e); } initGuideVars(); if (guide.getId()!=null){ _idGuide = guide.getId(); } _resourceDescription = guide.getDescription(); if (_resourceDescription != null) { _originalAuthor = _resourceDescription.getOriginalAuthor(); _details = _resourceDescription.getDetails(); _otherContributors = _resourceDescription.getOtherContributors(); _otherDetails = _resourceDescription.getOtherDetails(); } _language = guide.getLanguage(); _conceptGTCode = guide.getConcept(); _guideOntology = guide.getOntology(); _termDefinitions = getGuideOntology().getTermDefinitions(); if (_termDefinitions==null){ _termDefinitions = new HashMap<String, TermDefinition>(); }else{ check(getOriginalLanguageCode(), getTermDefinitions()); } _termBindings = getGuideOntology().getTermBindings(); if (_termBindings==null){ _termBindings = new HashMap<String, TermBinding>(); } _guideOntology.setTermDefinitions(_termDefinitions); _guideOntology.setTermBindings(_termBindings); generateGTCodesForArchetypeBindings(guide); try { _readableGuide = GuideImporter.importGuide(guide, getCurrentLanguageCode(), ArchetypeManager.getInstance()); } catch (InternalErrorException e) { ExceptionHandler.handle(e); } initResourceDescription(); updateOriginal(); } private void generateGTCodesForArchetypeBindings(Guide guide){ //Generate gt codes for archetype bindings (if missing) if (guide.getDefinition()!=null && guide.getDefinition().getArchetypeBindings()!=null){ List<String> abCodes = new ArrayList<String>(); abCodes.addAll(guide.getDefinition().getArchetypeBindings().keySet()); Collections.sort(abCodes); int gtNum = getNextTermNumber(); for(String abCode: abCodes){ if (abCode.startsWith(GuideDefinition.ARCHETYPE_BINDING_PREFIX)){ ArchetypeBinding archetypeBinding = guide.getDefinition().getArchetypeBindings().get(abCode); String gtCode = GT_HEADER+StringUtils.leftPad("" + (gtNum++), 4, "0"); guide.getDefinition().getArchetypeBindings().remove(abCode); archetypeBinding.setId(gtCode); guide.getDefinition().getArchetypeBindings().put(gtCode, archetypeBinding); } } } } // Check if all elements inside map have the same amount of gtcodes as the // ones in the original language, if not, add them private static void check(String originalLang, Map<String, TermDefinition> termDefinitionMap) { TermDefinition originalTermDefinition = termDefinitionMap.get(originalLang); for (String langCode : termDefinitionMap.keySet()) { if (!langCode.equals(originalLang)) { TermDefinition td = termDefinitionMap.get(langCode); for (String gtCode : originalTermDefinition.getTerms().keySet()) { if (!td.getTerms().containsKey(gtCode)) { Logger.getLogger(GDLEditor.class).warn( "Language '" + langCode + "' does not contain gt code '" + gtCode + "'. Will be added..."); Term term = getTermToDifferentLanguage(gtCode, originalTermDefinition.getTerms().get(gtCode), originalLang); td.getTerms().put(gtCode, term); } } } } } public boolean isModified() { String serializedGuide = null; try { Guide guide = constructCurrentGuide(); serializedGuide = GuideUtil.serializeGuide(guide); } catch (Exception e) { ExceptionHandler.handle(e); } if (_originalGuide != null && !_originalGuide.equals(serializedGuide)) { return true; } else { return false; } } public void cleanRedundantTerms() { Collection<String> gtCodesUsed = getGTCodesUsedInGuide(); for (TermDefinition termDefinition : getTermDefinitions().values()) { Collection<Term> terms = new ArrayList<Term>(termDefinition .getTerms().values()); for (Term term : terms) { if (!gtCodesUsed.contains(term.getId())) { termDefinition.getTerms().remove(term.getId()); } } } } public Collection<String> getGTCodesUsedInGuide() { TermDefinition td = getTermDefinitions().get(getCurrentLanguageCode()); if (td != null) { return td.getTerms().keySet(); } else { return Collections.emptyList(); } } public Collection<String> getGTCodesUsedInDefinitions() { Collection<String> gtCodes = new ArrayList<String>(); gtCodes.add(getConceptGTCode()); gtCodes.addAll(getRenderableRules().keySet()); return gtCodes; } public Collection<String> getGTCodesUsedInBindings() { Collection<String> gtCodes = new HashSet<String>(); for (TermBinding termBinding : getTermBindings().values()) { gtCodes.addAll(termBinding.getBindings().keySet()); } return gtCodes; } public void saveCompiledGuideAsObject(byte[] compiledGuide, Guide guide) { EditorController controller = EditorManager.getActiveEditorController(); String idGuide = controller.getEntityId(); if (idGuide == null) { idGuide = GDLEditorLanguageManager.getMessage("Guide"); } if (compiledGuide != null) { try { String guideSource = controller.getSerializedEntity(); if (guideSource != null) { JFileChooser fileChooser = new JFileChooser(); FileNameExtensionFilter filter = new FileNameExtensionFilter( GDLEditorLanguageManager.getMessage("Guide"), new String[] { "guide" }); fileChooser.setDialogTitle(GDLEditorLanguageManager .getMessage("SaveGuideAsObjectSD")); fileChooser.setFileFilter(filter); File file = new File(fileChooser.getFileSystemView() .getDefaultDirectory() + "/" + idGuide + ".guide"); fileChooser.setSelectedFile(file); int result = fileChooser.showSaveDialog(EditorManager .getActiveEditorWindow()); File guideFile = fileChooser.getSelectedFile(); if (result != JFileChooser.CANCEL_OPTION) { idGuide = guideFile.getName(); if (idGuide.endsWith(".guide")) { idGuide = idGuide .substring(0, idGuide.length() - 6); } GuideDTO guideDTO = new GuideDTOBuilder().setId(idGuide).setFormat(guideSource).setSource(CMTypeFormat.GDL_FORMAT.getFormat()).setGuideObject(IOUtils.getBytes(guide)).setCompiledGuide(compiledGuide).setLastUpdate(Calendar.getInstance().getTime()).createGuideDTO(); ObjectOutputStream output = new ObjectOutputStream( new BufferedOutputStream(new FileOutputStream( guideFile))); try { output.writeObject(guideDTO); } catch (Exception e) { ExceptionHandler.handle(e); } finally { output.close(); } } } } catch (Exception e) { ExceptionHandler.handle(e); } } } public ArchetypeInstantiationRuleLine addArchetypeReference( boolean showOnlyCDS) { ArchetypeInstantiationRuleLine airl = new ArchetypeInstantiationRuleLine(); airl.setGTCode(createNextGTCode(false)); RuleElementEditor.editArchetype( airl.getArchetypeReferenceRuleLineDefinitionElement(), showOnlyCDS); if (airl.getArchetypeReferenceRuleLineDefinitionElement().getValue() != null) { getDefinitionRuleLines().add(airl); return airl; } else { return null; } } private Collection<String> getArchetypeBindingCodesUsed(){ ArrayList<String> archetypeBindingCodesUsed = new ArrayList<String>(); for (RuleLine ruleLine : getDefinitionRuleLines().getRuleLines()){ if (ruleLine instanceof ArchetypeInstantiationRuleLine){ ArchetypeInstantiationRuleLine archetypeInstantiationRuleLine = (ArchetypeInstantiationRuleLine) ruleLine; archetypeBindingCodesUsed.add(archetypeInstantiationRuleLine.getGTCode()); } } return archetypeBindingCodesUsed; } public ArchetypeElementInstantiationRuleLine addArchetypeElement( ArchetypeInstantiationRuleLine airl) { ArchetypeElementInstantiationRuleLine aeirl = new ArchetypeElementInstantiationRuleLine(airl); aeirl.getGTCodeRuleLineElement().setValue(createNextLocalCode()); editRuleElement(aeirl.getArchetypeElementRuleLineDefinitionElement()); if (aeirl.getArchetypeElementRuleLineDefinitionElement().getValue() != null) { return aeirl; } else { aeirl.detachFromParent(); return null; } } public void setBusy(String description) { // getEditorPanel().setBusy(true); getInfoDialog().changeLoadingText(description); getInfoDialog().start(); } public void changeBusyText(String description) { getInfoDialog().changeLoadingText(description); } private InfoDialog getInfoDialog() { if (_infoDialog == null) { _infoDialog = new InfoDialog(EditorManager.getActiveEditorWindow()); } return _infoDialog; } public void setFree() { getInfoDialog().stop(); } private void checkGuideArchetypesAndTemplates(Guide guide) throws InternalErrorException, InstanceNotFoundException { if (guide == null || guide.getDefinition() == null || guide.getDefinition().getArchetypeBindings() == null) { return; } for (ArchetypeBinding archetypeBinding : guide.getDefinition().getArchetypeBindings().values()) { String archetypeId = archetypeBinding.getArchetypeId(); String templateId = archetypeBinding.getTemplateId(); if (templateId == null) { try { ArchetypeManager.getInstance().getArchetypes().getCMElement(archetypeId); } catch (InstanceNotFoundException e) { int result = ImportUtils.showImportArchetypeDialogAndAddToRepo( EditorManager.getActiveEditorWindow(), new File(archetypeId + ".adl")); if (result == JFileChooser.CANCEL_OPTION) { throw new InternalErrorException(new Exception("Archetype '" + archetypeId + "' not found.")); } } } else { try { ArchetypeManager.getInstance().getTemplates().getCMElement(templateId); } catch (InstanceNotFoundException e) { int result = ImportUtils.showImportTemplateDialog( EditorManager.getActiveEditorWindow(), new File(templateId + ".oet")); if (result == JFileChooser.CANCEL_OPTION) { throw new InternalErrorException(new Exception("Template '" + templateId + "' not found.")); } } } } } public static boolean checkParsedGuide(String guideSrc, Guide guide){ String guideSrcAux = GDLEditor.serializeGuide(guide); if (guide!=null){ Patch patch = DiffUtils.diff(stringToLines(guideSrc), stringToLines(guideSrcAux)); if (patch.getDeltas().isEmpty()){ return true; }else{ StringBuffer diff = new StringBuffer(); for (Delta delta : patch.getDeltas()) { diff.append("-------------------------------------\n"); diff.append(" line:"+delta.getOriginal().getPosition()+1+"\n"); diff.append(" original:"+delta.getOriginal().getLines()+"\n"); diff.append(" revised:"+delta.getRevised().getLines()+"\n"); } DialogLongMessageNotice dialog = new DialogLongMessageNotice( EditorManager.getActiveEditorWindow(), GDLEditorLanguageManager.getMessage("ErrorLoadingGuideT"), GDLEditorLanguageManager.getMessage("ErrorLoadingGuide"), diff.toString(), MessageType.WARNING_WITH_CANCEL ); dialog.setVisible(true); boolean result = dialog.getAnswer(); if (result){ return true; }else{ return false; } } }else{ return false; } } private static List<String> stringToLines(String str) { final List<String> lines = new ArrayList<String>(); for (String string : str.split("\n")) { lines.add(string.trim()); } return lines; } } /* * ***** BEGIN LICENSE BLOCK ***** Version: MPL 2.0/GPL 2.0/LGPL 2.1 * * The contents of this file are subject to the Mozilla Public License Version * 2.0 (the 'License'); you may not use this file except in compliance with the * License. You may obtain a copy of the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an 'AS IS' basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for * the specific language governing rights and limitations under the License. * * * The Initial Developers of the Original Code are Iago Corbal and Rong Chen. * Portions created by the Initial Developer are Copyright (C) 2012-2013 the * Initial Developer. All Rights Reserved. * * Contributor(s): * * Software distributed under the License is distributed on an 'AS IS' basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for * the specific language governing rights and limitations under the License. * * ***** END LICENSE BLOCK ***** */