KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > team > internal > core > mapping > DelegatingStorageMerger


1 /*******************************************************************************
2  * Copyright (c) 2006 IBM Corporation and others.
3  * All rights reserved. This program and the accompanying materials
4  * are made available under the terms of the Eclipse Public License v1.0
5  * which accompanies this distribution, and is available at
6  * http://www.eclipse.org/legal/epl-v10.html
7  *
8  * Contributors:
9  * IBM Corporation - initial API and implementation
10  *******************************************************************************/

11 package org.eclipse.team.internal.core.mapping;
12
13 import java.io.IOException JavaDoc;
14 import java.io.OutputStream JavaDoc;
15
16 import org.eclipse.core.resources.IFile;
17 import org.eclipse.core.resources.IStorage;
18 import org.eclipse.core.runtime.*;
19 import org.eclipse.core.runtime.content.*;
20 import org.eclipse.osgi.util.NLS;
21 import org.eclipse.team.core.Team;
22 import org.eclipse.team.core.TeamException;
23 import org.eclipse.team.core.mapping.IStorageMerger;
24 import org.eclipse.team.internal.core.*;
25
26 /**
27  * This storage merger delegates to the appropriate merger or returns a conflict
28  * if no merger is available.
29  * <p>
30  * The target storage is used to look for an appropriate merger. If the target
31  * is an {@link IFile}, the content type of the file is used. Otherwise, the
32  * {@link IContentTypeManager} is used to find an appropriate content type.If an
33  * appropriate merger is not found, a status containing the
34  * <code>CONFLICT</code> is returned.
35  *
36  */

37 public class DelegatingStorageMerger implements IStorageMerger {
38
39     private static IStreamMergerDelegate mergerDelegate;
40     private static DelegatingStorageMerger instance;
41     private final IContentType contentType;
42     
43     public DelegatingStorageMerger() {
44         contentType = null;
45     }
46     
47     public DelegatingStorageMerger(IContentType contentType) {
48         this.contentType = contentType;
49     }
50
51     /**
52      * Set the file merger that is used by the {@link #merge(OutputStream, String, IStorage, IStorage, IStorage, IProgressMonitor)}
53      * method. It is the responsibility of subclasses to provide a merger.
54      * If a merger is not provided, subclasses must override <code>performThreeWayMerge</code>.
55      * @param merger the merger used to merge files
56      */

57     public static void setMergerDelegate(IStreamMergerDelegate merger) {
58         mergerDelegate = merger;
59     }
60     
61     public static IStorageMerger getInstance() {
62         if (instance == null)
63             instance = new DelegatingStorageMerger();
64         return instance;
65     }
66     
67     /*
68      * (non-Javadoc)
69      *
70      * @see org.eclipse.team.core.mapping.IStorageMerger#merge(java.io.OutputStream,
71      * java.lang.String, org.eclipse.core.resources.IStorage,
72      * org.eclipse.core.resources.IStorage,
73      * org.eclipse.core.resources.IStorage,
74      * org.eclipse.core.runtime.IProgressMonitor)
75      */

76     public IStatus merge(OutputStream JavaDoc output, String JavaDoc outputEncoding,
77             IStorage ancestor, IStorage target, IStorage other,
78             IProgressMonitor monitor) throws CoreException {
79         IStorageMerger merger = findMerger(target);
80         if (merger == null)
81             return new Status(IStatus.WARNING, TeamPlugin.ID, CONFLICT,
82                     Messages.DelegatingStorageMerger_0, null);
83         if (ancestor == null && !merger.canMergeWithoutAncestor()) {
84             return new Status(IStatus.WARNING, TeamPlugin.ID, CONFLICT,
85                     NLS.bind(Messages.MergeContext_1, new String JavaDoc[] { target.getFullPath().toString() }), null);
86         }
87         return merger.merge(output, outputEncoding, ancestor, target, other, monitor);
88     }
89
90     protected IStorageMerger findMerger(IStorage target) throws CoreException {
91         IStorageMerger merger = null;
92         if (contentType != null) {
93             // A particular merger has been requested
94
merger = getMerger(contentType);
95             if (merger != null) {
96                 return merger;
97             } else {
98                 // The requested merger is not available but still try and find another
99
TeamPlugin.log(IStatus.ERROR, NLS.bind("Storage merger for {0} not available", contentType.getId()), null); //$NON-NLS-1$
100
}
101         }
102         CoreException exception = null;
103         try {
104             IContentType type = getContentType(target);
105             if (type != null)
106                 merger = getMerger(type);
107         } catch (CoreException e) {
108             exception = e;
109         }
110         // If an exception occurred trying to find a content type,
111
// try using the extension before failing
112
if (merger == null) {
113             merger = getMerger(target.getName());
114             if (merger == null) {
115                 // If team thinks the file is text, try to get a text merger for the file
116
int type = getType(target);
117                 if (type == Team.TEXT)
118                     merger = getTextMerger();
119                 if (merger == null) {
120                     // As a last resort, look for a stream merger
121
merger = findAndWrapStreamMerger(target);
122                 }
123             }
124         }
125         if (exception != null) {
126             if (merger == null) {
127                 // No merger was found so report the error
128
throw exception;
129             } else {
130                 // If an extension based merger was found, log the error
131
TeamPlugin.log(exception);
132             }
133         }
134         return merger;
135     }
136
137     protected int getType(IStorage target) {
138         return Team.getFileContentManager().getType(target);
139     }
140
141     private IStorageMerger findAndWrapStreamMerger(IStorage target) {
142         if (mergerDelegate != null) {
143             IStorageMerger merger = mergerDelegate.findMerger(target);
144             return merger;
145         }
146         return null;
147     }
148
149     protected IStorageMerger getTextMerger() {
150         return new DelegatingStorageMerger(Platform.getContentTypeManager().getContentType(IContentTypeManager.CT_TEXT));
151     }
152
153     private IStorageMerger getMerger(String JavaDoc name) {
154         String JavaDoc extension = getExtension(name);
155         if (extension != null)
156             return StorageMergerRegistry.getInstance().createStreamMerger(extension);
157         return null;
158     }
159
160     public static String JavaDoc getExtension(String JavaDoc name) {
161         int index = name.lastIndexOf('.');
162         if (index == -1) {
163             return null;
164         }
165         return name.substring(index + 1);
166     }
167
168     private IStorageMerger getMerger(IContentType type) {
169         IStorageMerger merger = StorageMergerRegistry.getInstance().createStreamMerger(type);
170         return merger;
171     }
172
173     /*
174      * Find the content type for the given storage and return null if a content
175      * type cannot be found. Any exceptions that occur when trying to determine
176      * the content type are propogated.
177      */

178     public static IContentType getContentType(IStorage target) throws CoreException {
179         if (target instanceof IFile) {
180             IFile file = (IFile) target;
181             IContentDescription contentDescription = file.getContentDescription();
182             if (contentDescription != null) {
183                 IContentType contentType = contentDescription.getContentType();
184                 return contentType;
185             }
186         } else {
187             IContentTypeManager manager = Platform.getContentTypeManager();
188             try {
189                 IContentType type = manager.findContentTypeFor(target
190                         .getContents(), target.getName());
191                 return type;
192             } catch (IOException JavaDoc e) {
193                 String JavaDoc name = target.getName();
194                 if (target.getFullPath() != null) {
195                     name = target.getFullPath().toString();
196                 }
197                 throw new TeamException(new Status(
198                     IStatus.ERROR,
199                     TeamPlugin.ID,
200                     INTERNAL_ERROR,
201                     NLS.bind(Messages.DelegatingStorageMerger_1,name), e));
202             }
203         }
204         return null;
205     }
206
207     /* (non-Javadoc)
208      * @see org.eclipse.team.core.mapping.IStorageMerger#canMergeWithoutAncestor()
209      */

210     public boolean canMergeWithoutAncestor() {
211         return false;
212     }
213
214 }
215
Popular Tags