Alternative versions for build.properties added. Current state set to "dependencies...
[taxeditor.git] / eu.etaxonomy.taxeditor.bulkeditor / src / main / java / eu / etaxonomy / taxeditor / annotatedlineeditor / AnnotatedLineEditor.java
1 // $Id$
2 /**
3 * Copyright (C) 2007 EDIT
4 * European Distributed Institute of Taxonomy
5 * http://www.e-taxonomy.eu
6 *
7 * The contents of this file are subject to the Mozilla Public License Version 1.1
8 * See LICENSE.TXT at the top of this package for the full license terms.
9 */
10 package eu.etaxonomy.taxeditor.annotatedlineeditor;
11
12 import java.util.Iterator;
13
14 import org.eclipse.core.runtime.CoreException;
15 import org.eclipse.core.runtime.IProgressMonitor;
16 import org.eclipse.jface.text.BadLocationException;
17 import org.eclipse.jface.text.source.IAnnotationModel;
18 import org.eclipse.jface.text.source.ISourceViewer;
19 import org.eclipse.jface.text.source.IVerticalRuler;
20 import org.eclipse.swt.widgets.Composite;
21 import org.eclipse.ui.IEditorInput;
22 import org.eclipse.ui.PlatformUI;
23 import org.eclipse.ui.editors.text.TextEditor;
24 import org.eclipse.ui.texteditor.IDocumentProvider;
25
26 import eu.etaxonomy.cdm.api.conversation.ConversationHolder;
27 import eu.etaxonomy.cdm.api.conversation.IConversationEnabled;
28 import eu.etaxonomy.cdm.api.service.IOccurrenceService;
29 import eu.etaxonomy.cdm.hibernate.HibernateProxyHelper;
30 import eu.etaxonomy.cdm.model.common.CdmBase;
31 import eu.etaxonomy.cdm.persistence.hibernate.CdmDataChangeMap;
32 import eu.etaxonomy.taxeditor.bulkeditor.input.AbstractBulkEditorInput;
33 import eu.etaxonomy.taxeditor.operation.IPostOperationEnabled;
34 import eu.etaxonomy.taxeditor.store.CdmStore;
35
36 /**
37 * A list-based editor, where each line in the editor's document is associated with a domain object.
38 * <p>
39 * Extending classes must set:
40 * <ul>
41 * <li>an {@link IEntityPersistenceService} for interacting with the persistence layer; and
42 * <li>an {@link ILineDisplayStrategy} for various visual manifestations of the domain object.
43 * </ul>
44 *
45 * @author p.ciardelli
46 * @created 25.06.2009
47 * @version 1.0
48 */
49 public class AnnotatedLineEditor extends TextEditor implements IConversationEnabled, IPostOperationEnabled {
50
51 protected ConversationHolder conversation;
52
53 private IEntityPersistenceService persistenceService;
54 protected ILineDisplayStrategy lineDisplayStrategy;
55
56
57 /**
58 * <p>Constructor for AnnotatedLineEditor.</p>
59 *
60 * @param conversation a {@link eu.etaxonomy.cdm.api.conversation.ConversationHolder} object.
61 */
62 public AnnotatedLineEditor(ConversationHolder conversation) {
63 this.conversation = conversation;
64 }
65
66 /* (non-Javadoc)
67 * @see org.eclipse.ui.editors.text.TextEditor#doSetInput(org.eclipse.ui.IEditorInput)
68 */
69 /** {@inheritDoc} */
70 @Override
71 protected void doSetInput(IEditorInput input) throws CoreException {
72
73 AnnotatedLineDocumentProvider provider = new AnnotatedLineDocumentProvider(input);
74
75 provider.setLineDisplayStrategy(lineDisplayStrategy, input);
76 setDocumentProvider(provider);
77
78 super.doSetInput(input);
79 }
80
81 /**
82 * <p>Setter for the field <code>persistenceService</code>.</p>
83 *
84 * @param persistenceService a {@link eu.etaxonomy.taxeditor.annotatedlineeditor.IEntityPersistenceService} object.
85 */
86 protected void setPersistenceService(
87 IEntityPersistenceService persistenceService) {
88 this.persistenceService = persistenceService;
89 }
90
91 /**
92 * <p>Getter for the field <code>persistenceService</code>.</p>
93 *
94 * @return a {@link eu.etaxonomy.taxeditor.annotatedlineeditor.IEntityPersistenceService} object.
95 */
96 protected IEntityPersistenceService getPersistenceService() {
97 return persistenceService;
98 }
99
100 /**
101 * <p>Setter for the field <code>lineDisplayStrategy</code>.</p>
102 *
103 * @param lineDisplayStrategy a {@link eu.etaxonomy.taxeditor.annotatedlineeditor.ILineDisplayStrategy} object.
104 */
105 protected void setLineDisplayStrategy(
106 ILineDisplayStrategy lineDisplayStrategy) {
107 this.lineDisplayStrategy = lineDisplayStrategy;
108 }
109
110 /** {@inheritDoc} */
111 @Override
112 protected ISourceViewer createSourceViewer(Composite parent,
113 IVerticalRuler ruler, int styles) {
114
115 fAnnotationAccess= getAnnotationAccess();
116 fOverviewRuler= createOverviewRuler(getSharedColors());
117 LineSelectionViewer viewer = new LineSelectionViewer(parent, ruler, getOverviewRuler(),
118 isOverviewRulerVisible(), styles);
119 // isOverviewRulerVisible(), styles | SWT.WRAP);
120 getSourceViewerDecorationSupport(viewer);
121
122 return viewer;
123 }
124
125 /**
126 * Create an annotated line with an "empty" entity, i.e. using the editor
127 * input's default entity type and a zero-length title cache.
128 *
129 * @return a {@link eu.etaxonomy.taxeditor.annotatedlineeditor.LineAnnotation} object.
130 */
131 public LineAnnotation createAnnotatedLineNewObject() {
132
133 // Create new object
134
135 AnnotatedLineDocumentProvider documentProvider = (AnnotatedLineDocumentProvider) getDocumentProvider();
136 IEntityCreator entityCreator = documentProvider.getEntityCreator(getEditorInput());
137 Object entity = entityCreator.createEntity(null);
138
139 LineAnnotation annotation = createAnnotatedLine(entity);
140 if (annotation != null) {
141 annotation.markAsNew(true);
142 }
143 return annotation;
144 }
145
146 /**
147 * Create an annotated line, first creating an entity of type "key" - this key
148 * must be recognized by the editor's entity creator.
149 *
150 * @param key a {@link java.lang.Object} object.
151 * @param titleCache a {@link java.lang.String} object.
152 * @return a {@link eu.etaxonomy.taxeditor.annotatedlineeditor.LineAnnotation} object.
153 */
154 public LineAnnotation createAnnotatedLineNewObject(Object key, String titleCache) {
155
156
157
158 // Create new object
159 Object entity = ((AnnotatedLineDocumentProvider) getDocumentProvider()).
160 getEntityCreator(getEditorInput()).createEntity(key, titleCache);
161 // checks if the creator also saves the entity (in a different conversation), in which case
162 // we need to bind back this editors conversation
163 // we also need to reload the entity because the conversation used to
164 // to create / save the entity may have been closed
165 if(entity != null && ((AnnotatedLineDocumentProvider) getDocumentProvider()).getEntityCreator(getEditorInput()).savesEntity()) {
166 getConversationHolder().bind();
167 //FIXME: why do we use IOccurrenceService here? is this generic?
168 //because this method is only invoked by the handler which is used in the
169 //specimen bulk editor. This is unsafe and should be refactored!
170 Object object = CdmStore.getService(IOccurrenceService.class).load(((CdmBase)entity).getUuid());
171 entity = HibernateProxyHelper.deproxy(object);
172 }
173
174 if(entity == null) {
175 return null;
176 }
177 LineAnnotation annotation = createAnnotatedLine(entity);
178 if (annotation != null) {
179 annotation.markAsNew(true);
180 }
181
182 return annotation;
183
184 }
185
186 @Override
187 public boolean isDirty() {
188 return super.isDirty();
189 }
190
191 /**
192 * Creates an annotated line at the end of the document. The annotation contains the entity.
193 *
194 * @param entity a {@link java.lang.Object} object.
195 * @return a {@link eu.etaxonomy.taxeditor.annotatedlineeditor.LineAnnotation} object.
196 */
197 public LineAnnotation createAnnotatedLine(Object entity) {
198
199 IEditorInput input = getEditorInput();
200 this.conversation.close();
201 this.conversation = ((AbstractBulkEditorInput)input).getConversation();
202 AnnotatedLineDocumentProvider provider = (AnnotatedLineDocumentProvider) getDocumentProvider();
203
204 LineAnnotation annotation = null;
205 try {
206 annotation = provider.createAnnotatedLine(input, entity);
207
208 // Jump to new line
209 IAnnotationModel model = provider.getAnnotationModel(input);
210 if(model != null){
211 int start= model.getPosition(annotation).getOffset();
212 selectAndReveal(start, 0);
213 }
214
215 } catch (BadLocationException e) {
216 // TODO Auto-generated catch block
217 e.printStackTrace();
218 }
219 return annotation;
220 }
221
222 /**
223 * <p>removeAnnotatedLine</p>
224 *
225 * @param lineno a int.
226 */
227 public void removeAnnotatedLine(int lineno) {
228 ((AnnotatedLineDocumentProvider) getDocumentProvider()).removeAnnotatedLine(lineno);
229 }
230
231 /**
232 * <p>removeAnnotatedLine</p>
233 *
234 * @param annotation a {@link eu.etaxonomy.taxeditor.annotatedlineeditor.LineAnnotation} object.
235 */
236 public void removeAnnotatedLine(LineAnnotation annotation) {
237 ((AnnotatedLineDocumentProvider) getDocumentProvider()).removeAnnotatedLine(annotation);
238
239 }
240
241 /* (non-Javadoc)
242 * @see org.eclipse.ui.texteditor.AbstractTextEditor#doSave(org.eclipse.core.runtime.IProgressMonitor)
243 */
244 /** {@inheritDoc} */
245 @Override
246 public void doSave(IProgressMonitor progressMonitor) {
247 if (getConversationHolder() != null) {
248 if( ! getConversationHolder().isBound()){
249 getConversationHolder().bind();
250 }
251 super.doSave(progressMonitor);
252 getConversationHolder().commit(true);
253 } else {
254 super.doSave(progressMonitor);
255 }
256 firePropertyChange(PROP_DIRTY);
257 }
258
259 /* (non-Javadoc)
260 * @see org.eclipse.ui.texteditor.AbstractTextEditor#setFocus()
261 */
262 /** {@inheritDoc} */
263 @Override
264 public void setFocus() {
265 super.setFocus();
266 if (getConversationHolder() != null) {
267 getConversationHolder().bind();
268 }
269 ((AbstractBulkEditorInput)getEditorInput()).bind();
270 PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell().setFocus();
271 // TODO pass focus to underlying widgets
272 }
273
274 /* (non-Javadoc)
275 * @see eu.etaxonomy.cdm.api.conversation.IConversationEnabled#getConversationHolder()
276 */
277 /**
278 * <p>getConversationHolder</p>
279 *
280 * @return a {@link eu.etaxonomy.cdm.api.conversation.ConversationHolder} object.
281 */
282 @Override
283 public ConversationHolder getConversationHolder() {
284 return conversation;
285 }
286
287 /* (non-Javadoc)
288 * @see eu.etaxonomy.cdm.persistence.hibernate.ICdmPostDataChangeObserver#update(eu.etaxonomy.cdm.persistence.hibernate.CdmDataChangeMap)
289 */
290 /** {@inheritDoc} */
291 @Override
292 public void update(CdmDataChangeMap changeEvents) {}
293
294 /**
295 * Refreshes text in all lines.
296 */
297 protected void refreshLineDisplay() {
298 IDocumentProvider provider = getDocumentProvider();
299 IEditorInput input = getEditorInput();
300 IAnnotationModel model = provider.getAnnotationModel(input);
301 Iterator iter = getDocumentProvider().getAnnotationModel(getEditorInput()).getAnnotationIterator();
302 while (iter.hasNext()) {
303 Object next = iter.next();
304 if (next instanceof LineAnnotation) {
305 LineAnnotation annotation = (LineAnnotation) next;
306 ((AnnotatedLineDocumentProvider) getDocumentProvider()).
307 updateLineFromAnnotation(annotation);
308 }
309 }
310 }
311
312 /* (non-Javadoc)
313 * @see eu.etaxonomy.taxeditor.operations.IPostOperationEnabled#postOperation(eu.etaxonomy.cdm.model.common.CdmBase)
314 */
315 /** {@inheritDoc} */
316 @Override
317 public boolean postOperation(CdmBase objectAffectedByOperation) {
318 refreshLineDisplay();
319
320 return true;
321 }
322
323 /* (non-Javadoc)
324 * @see org.eclipse.ui.editors.text.TextEditor#dispose()
325 */
326 /** {@inheritDoc} */
327 @Override
328 public void dispose() {
329 super.dispose();
330 conversation.close();
331 ((AbstractBulkEditorInput)getEditorInput()).dispose();
332 }
333
334 /**
335 * <p>onComplete</p>
336 *
337 * @return a boolean.
338 */
339 @Override
340 public boolean onComplete() {
341 // TODO Auto-generated method stub
342 return false;
343 }
344
345
346 }