2 * Copyright (C) 2007 EDIT
3 * European Distributed Institute of Taxonomy
4 * http://www.e-taxonomy.eu
6 * The contents of this file are subject to the Mozilla Public License Version 1.1
7 * See LICENSE.TXT at the top of this package for the full license terms.
9 package eu
.etaxonomy
.taxeditor
.annotatedlineeditor
;
11 import java
.util
.Iterator
;
13 import org
.eclipse
.core
.runtime
.CoreException
;
14 import org
.eclipse
.core
.runtime
.IProgressMonitor
;
15 import org
.eclipse
.jface
.text
.BadLocationException
;
16 import org
.eclipse
.jface
.text
.source
.IAnnotationModel
;
17 import org
.eclipse
.jface
.text
.source
.ISourceViewer
;
18 import org
.eclipse
.jface
.text
.source
.IVerticalRuler
;
19 import org
.eclipse
.swt
.widgets
.Composite
;
20 import org
.eclipse
.ui
.IEditorInput
;
21 import org
.eclipse
.ui
.PlatformUI
;
22 import org
.eclipse
.ui
.editors
.text
.TextEditor
;
23 import org
.eclipse
.ui
.texteditor
.IDocumentProvider
;
25 import eu
.etaxonomy
.cdm
.api
.conversation
.ConversationHolder
;
26 import eu
.etaxonomy
.cdm
.api
.conversation
.IConversationEnabled
;
27 import eu
.etaxonomy
.cdm
.api
.service
.IOccurrenceService
;
28 import eu
.etaxonomy
.cdm
.hibernate
.HibernateProxyHelper
;
29 import eu
.etaxonomy
.cdm
.model
.common
.CdmBase
;
30 import eu
.etaxonomy
.cdm
.persistence
.hibernate
.CdmDataChangeMap
;
31 import eu
.etaxonomy
.taxeditor
.bulkeditor
.input
.AbstractBulkEditorInput
;
32 import eu
.etaxonomy
.taxeditor
.operation
.IPostOperationEnabled
;
33 import eu
.etaxonomy
.taxeditor
.store
.CdmStore
;
36 * A list-based editor, where each line in the editor's document is associated with a domain object.
38 * Extending classes must set:
40 * <li>an {@link IEntityPersistenceService} for interacting with the persistence layer; and
41 * <li>an {@link ILineDisplayStrategy} for various visual manifestations of the domain object.
48 public class AnnotatedLineEditor
extends TextEditor
implements IConversationEnabled
, IPostOperationEnabled
{
50 protected ConversationHolder conversation
;
52 private IEntityPersistenceService persistenceService
;
53 protected ILineDisplayStrategy lineDisplayStrategy
;
57 * <p>Constructor for AnnotatedLineEditor.</p>
59 * @param conversation a {@link eu.etaxonomy.cdm.api.conversation.ConversationHolder} object.
61 public AnnotatedLineEditor(ConversationHolder conversation
) {
62 this.conversation
= conversation
;
66 * @see org.eclipse.ui.editors.text.TextEditor#doSetInput(org.eclipse.ui.IEditorInput)
70 protected void doSetInput(IEditorInput input
) throws CoreException
{
72 AnnotatedLineDocumentProvider provider
= new AnnotatedLineDocumentProvider(input
);
74 provider
.setLineDisplayStrategy(lineDisplayStrategy
, input
);
75 setDocumentProvider(provider
);
77 super.doSetInput(input
);
81 * <p>Setter for the field <code>persistenceService</code>.</p>
83 * @param persistenceService a {@link eu.etaxonomy.taxeditor.annotatedlineeditor.IEntityPersistenceService} object.
85 protected void setPersistenceService(
86 IEntityPersistenceService persistenceService
) {
87 this.persistenceService
= persistenceService
;
91 * <p>Getter for the field <code>persistenceService</code>.</p>
93 * @return a {@link eu.etaxonomy.taxeditor.annotatedlineeditor.IEntityPersistenceService} object.
95 protected IEntityPersistenceService
getPersistenceService() {
96 return persistenceService
;
100 * <p>Setter for the field <code>lineDisplayStrategy</code>.</p>
102 * @param lineDisplayStrategy a {@link eu.etaxonomy.taxeditor.annotatedlineeditor.ILineDisplayStrategy} object.
104 protected void setLineDisplayStrategy(
105 ILineDisplayStrategy lineDisplayStrategy
) {
106 this.lineDisplayStrategy
= lineDisplayStrategy
;
111 protected ISourceViewer
createSourceViewer(Composite parent
,
112 IVerticalRuler ruler
, int styles
) {
114 fAnnotationAccess
= getAnnotationAccess();
115 fOverviewRuler
= createOverviewRuler(getSharedColors());
116 LineSelectionViewer viewer
= new LineSelectionViewer(parent
, ruler
, getOverviewRuler(),
117 isOverviewRulerVisible(), styles
);
118 // isOverviewRulerVisible(), styles | SWT.WRAP);
119 getSourceViewerDecorationSupport(viewer
);
125 * Create an annotated line with an "empty" entity, i.e. using the editor
126 * input's default entity type and a zero-length title cache.
128 * @return a {@link eu.etaxonomy.taxeditor.annotatedlineeditor.LineAnnotation} object.
130 public LineAnnotation
createAnnotatedLineNewObject() {
134 AnnotatedLineDocumentProvider documentProvider
= (AnnotatedLineDocumentProvider
) getDocumentProvider();
135 IEntityCreator entityCreator
= documentProvider
.getEntityCreator(getEditorInput());
136 Object entity
= entityCreator
.createEntity(null);
138 LineAnnotation annotation
= createAnnotatedLine(entity
);
139 if (annotation
!= null) {
140 annotation
.markAsNew(true);
146 * Create an annotated line, first creating an entity of type "key" - this key
147 * must be recognized by the editor's entity creator.
149 * @param key a {@link java.lang.Object} object.
150 * @param titleCache a {@link java.lang.String} object.
151 * @return a {@link eu.etaxonomy.taxeditor.annotatedlineeditor.LineAnnotation} object.
153 public LineAnnotation
createAnnotatedLineNewObject(Object key
, String titleCache
) {
158 Object entity
= ((AnnotatedLineDocumentProvider
) getDocumentProvider()).
159 getEntityCreator(getEditorInput()).createEntity(key
, titleCache
);
160 // checks if the creator also saves the entity (in a different conversation), in which case
161 // we need to bind back this editors conversation
162 // we also need to reload the entity because the conversation used to
163 // to create / save the entity may have been closed
164 if(entity
!= null && ((AnnotatedLineDocumentProvider
) getDocumentProvider()).getEntityCreator(getEditorInput()).savesEntity()) {
165 getConversationHolder().bind();
166 //FIXME: why do we use IOccurrenceService here? is this generic?
167 //because this method is only invoked by the handler which is used in the
168 //specimen bulk editor. This is unsafe and should be refactored!
169 Object object
= CdmStore
.getService(IOccurrenceService
.class).load(((CdmBase
)entity
).getUuid());
170 entity
= HibernateProxyHelper
.deproxy(object
);
176 LineAnnotation annotation
= createAnnotatedLine(entity
);
177 if (annotation
!= null) {
178 annotation
.markAsNew(true);
186 public boolean isDirty() {
187 return super.isDirty();
191 * Creates an annotated line at the end of the document. The annotation contains the entity.
193 * @param entity a {@link java.lang.Object} object.
194 * @return a {@link eu.etaxonomy.taxeditor.annotatedlineeditor.LineAnnotation} object.
196 public LineAnnotation
createAnnotatedLine(Object entity
) {
198 IEditorInput input
= getEditorInput();
199 this.conversation
.close();
200 this.conversation
= ((AbstractBulkEditorInput
)input
).getConversation();
201 AnnotatedLineDocumentProvider provider
= (AnnotatedLineDocumentProvider
) getDocumentProvider();
203 LineAnnotation annotation
= null;
205 annotation
= provider
.createAnnotatedLine(input
, entity
);
208 IAnnotationModel model
= provider
.getAnnotationModel(input
);
210 int start
= model
.getPosition(annotation
).getOffset();
211 selectAndReveal(start
, 0);
214 } catch (BadLocationException e
) {
215 // TODO Auto-generated catch block
222 * <p>removeAnnotatedLine</p>
224 * @param lineno a int.
226 public void removeAnnotatedLine(int lineno
) {
227 ((AnnotatedLineDocumentProvider
) getDocumentProvider()).removeAnnotatedLine(lineno
);
231 * <p>removeAnnotatedLine</p>
233 * @param annotation a {@link eu.etaxonomy.taxeditor.annotatedlineeditor.LineAnnotation} object.
235 public void removeAnnotatedLine(LineAnnotation annotation
) {
236 ((AnnotatedLineDocumentProvider
) getDocumentProvider()).removeAnnotatedLine(annotation
);
241 * @see org.eclipse.ui.texteditor.AbstractTextEditor#doSave(org.eclipse.core.runtime.IProgressMonitor)
245 public void doSave(IProgressMonitor progressMonitor
) {
246 if (getConversationHolder() != null) {
247 if( ! getConversationHolder().isBound()){
248 getConversationHolder().bind();
250 super.doSave(progressMonitor
);
251 getConversationHolder().commit(true);
253 super.doSave(progressMonitor
);
255 firePropertyChange(PROP_DIRTY
);
259 * @see org.eclipse.ui.texteditor.AbstractTextEditor#setFocus()
263 public void setFocus() {
265 if (getConversationHolder() != null) {
266 getConversationHolder().bind();
268 ((AbstractBulkEditorInput
)getEditorInput()).bind();
269 PlatformUI
.getWorkbench().getActiveWorkbenchWindow().getShell().setFocus();
270 // TODO pass focus to underlying widgets
274 * @see eu.etaxonomy.cdm.api.conversation.IConversationEnabled#getConversationHolder()
277 * <p>getConversationHolder</p>
279 * @return a {@link eu.etaxonomy.cdm.api.conversation.ConversationHolder} object.
282 public ConversationHolder
getConversationHolder() {
287 * @see eu.etaxonomy.cdm.persistence.hibernate.ICdmPostDataChangeObserver#update(eu.etaxonomy.cdm.persistence.hibernate.CdmDataChangeMap)
291 public void update(CdmDataChangeMap changeEvents
) {}
294 * Refreshes text in all lines.
296 protected void refreshLineDisplay() {
297 IDocumentProvider provider
= getDocumentProvider();
298 IEditorInput input
= getEditorInput();
299 IAnnotationModel model
= provider
.getAnnotationModel(input
);
300 Iterator iter
= getDocumentProvider().getAnnotationModel(getEditorInput()).getAnnotationIterator();
301 while (iter
.hasNext()) {
302 Object next
= iter
.next();
303 if (next
instanceof LineAnnotation
) {
304 LineAnnotation annotation
= (LineAnnotation
) next
;
305 ((AnnotatedLineDocumentProvider
) getDocumentProvider()).
306 updateLineFromAnnotation(annotation
);
312 * @see eu.etaxonomy.taxeditor.operations.IPostOperationEnabled#postOperation(eu.etaxonomy.cdm.model.common.CdmBase)
316 public boolean postOperation(CdmBase objectAffectedByOperation
) {
317 refreshLineDisplay();
323 * @see org.eclipse.ui.editors.text.TextEditor#dispose()
327 public void dispose() {
329 conversation
.close();
330 ((AbstractBulkEditorInput
)getEditorInput()).dispose();
339 public boolean onComplete() {
340 // TODO Auto-generated method stub