Lines 68-84
Link Here
|
68 |
|
68 |
|
69 |
import javax.swing.event.ChangeEvent; |
69 |
import javax.swing.event.ChangeEvent; |
70 |
import javax.swing.event.ChangeListener; |
70 |
import javax.swing.event.ChangeListener; |
|
|
71 |
import org.netbeans.api.annotations.common.NonNull; |
72 |
import org.netbeans.api.annotations.common.NullAllowed; |
71 |
|
73 |
|
72 |
import org.netbeans.api.java.classpath.ClassPath; |
74 |
import org.netbeans.api.java.classpath.ClassPath; |
73 |
import org.netbeans.api.java.queries.AnnotationProcessingQuery; |
75 |
import org.netbeans.api.java.queries.AnnotationProcessingQuery; |
74 |
import org.netbeans.api.java.queries.BinaryForSourceQuery; |
|
|
75 |
import org.netbeans.api.java.queries.BinaryForSourceQuery.Result; |
76 |
import org.netbeans.api.java.queries.SourceForBinaryQuery; |
76 |
import org.netbeans.api.java.queries.SourceForBinaryQuery; |
77 |
import org.netbeans.api.java.source.BuildArtifactMapper.ArtifactsUpdated; |
77 |
import org.netbeans.api.java.source.BuildArtifactMapper.ArtifactsUpdated; |
78 |
import org.netbeans.api.java.source.SourceUtils; |
78 |
import org.netbeans.api.java.source.SourceUtils; |
79 |
import org.netbeans.api.queries.FileBuiltQuery; |
79 |
import org.netbeans.api.queries.FileBuiltQuery; |
80 |
import org.netbeans.api.queries.FileBuiltQuery.Status; |
80 |
import org.netbeans.api.queries.FileBuiltQuery.Status; |
81 |
import org.netbeans.api.queries.VisibilityQuery; |
81 |
import org.netbeans.api.queries.VisibilityQuery; |
|
|
82 |
import org.netbeans.modules.java.preprocessorbridge.api.CompileOnSaveActionQuery; |
83 |
import org.netbeans.modules.java.preprocessorbridge.spi.CompileOnSaveAction; |
82 |
import org.netbeans.modules.java.source.indexing.COSSynchronizingIndexer; |
84 |
import org.netbeans.modules.java.source.indexing.COSSynchronizingIndexer; |
83 |
import org.netbeans.modules.java.source.indexing.JavaIndex; |
85 |
import org.netbeans.modules.java.source.indexing.JavaIndex; |
84 |
import org.netbeans.modules.java.source.parsing.FileObjects; |
86 |
import org.netbeans.modules.java.source.parsing.FileObjects; |
Lines 90-96
Link Here
|
90 |
import org.netbeans.modules.parsing.spi.indexing.ErrorsCache; |
92 |
import org.netbeans.modules.parsing.spi.indexing.ErrorsCache; |
91 |
import org.netbeans.spi.queries.FileBuiltQueryImplementation; |
93 |
import org.netbeans.spi.queries.FileBuiltQueryImplementation; |
92 |
import org.openide.filesystems.FileObject; |
94 |
import org.openide.filesystems.FileObject; |
93 |
import org.openide.filesystems.FileStateInvalidException; |
|
|
94 |
import org.openide.filesystems.FileUtil; |
95 |
import org.openide.filesystems.FileUtil; |
95 |
import org.openide.util.ChangeSupport; |
96 |
import org.openide.util.ChangeSupport; |
96 |
import org.openide.util.Exceptions; |
97 |
import org.openide.util.Exceptions; |
Lines 99-104
Link Here
|
99 |
import org.openide.util.BaseUtilities; |
100 |
import org.openide.util.BaseUtilities; |
100 |
import org.openide.util.Lookup; |
101 |
import org.openide.util.Lookup; |
101 |
import org.openide.util.WeakSet; |
102 |
import org.openide.util.WeakSet; |
|
|
103 |
import org.openide.util.lookup.ServiceProvider; |
102 |
|
104 |
|
103 |
/** |
105 |
/** |
104 |
* |
106 |
* |
Lines 175-403
Link Here
|
175 |
} |
177 |
} |
176 |
} |
178 |
} |
177 |
|
179 |
|
178 |
private static File getTarget(URL source) { |
|
|
179 |
Result binaryRoots = BinaryForSourceQuery.findBinaryRoots(source); |
180 |
|
181 |
File result = null; |
182 |
|
183 |
for (URL u : binaryRoots.getRoots()) { |
184 |
assert u != null : "Null in BinaryForSourceQuery.Result.roots: " + binaryRoots; //NOI18N |
185 |
if (u == null) { |
186 |
continue; |
187 |
} |
188 |
File f = FileUtil.archiveOrDirForURL(u); |
189 |
|
190 |
try { |
191 |
if (FileUtil.isArchiveFile(BaseUtilities.toURI(f).toURL())) { |
192 |
continue; |
193 |
} |
194 |
|
195 |
if (f != null && result != null) { |
196 |
Logger.getLogger(BuildArtifactMapperImpl.class.getName()).log(Level.WARNING, "More than one binary directory for root: {0}", source.toExternalForm()); |
197 |
return null; |
198 |
} |
199 |
|
200 |
result = f; |
201 |
} catch (MalformedURLException ex) { |
202 |
Exceptions.printStackTrace(ex); |
203 |
} |
204 |
} |
205 |
|
206 |
return result; |
207 |
} |
208 |
|
209 |
@SuppressWarnings("deprecation") |
180 |
@SuppressWarnings("deprecation") |
210 |
public static Boolean ensureBuilt(URL sourceRoot, Object context, boolean copyResources, boolean keepResourceUpToDate) throws IOException { |
181 |
public static Boolean ensureBuilt(URL sourceRoot, Object context, boolean copyResources, boolean keepResourceUpToDate) throws IOException { |
211 |
File targetFolder = getTarget(sourceRoot); |
182 |
final CompileOnSaveAction a = CompileOnSaveActionQuery.getAction(sourceRoot); |
212 |
|
183 |
if (a != null) { |
213 |
if (targetFolder == null) { |
184 |
final CompileOnSaveAction.Context ctx = CompileOnSaveAction.Context.sync( |
214 |
return null; |
185 |
sourceRoot, |
|
|
186 |
copyResources, |
187 |
keepResourceUpToDate, |
188 |
context); |
189 |
return a.performAction(ctx); |
215 |
} |
190 |
} |
216 |
|
191 |
return null; |
217 |
try { |
|
|
218 |
SourceUtils.waitScanFinished(); |
219 |
} catch (InterruptedException e) { |
220 |
//Not Important |
221 |
LOG.log(Level.FINE, null, e); |
222 |
return null; |
223 |
} |
224 |
|
225 |
if (JavaIndex.ensureAttributeValue(sourceRoot, DIRTY_ROOT, null)) { |
226 |
IndexingManager.getDefault().refreshIndexAndWait(sourceRoot, null); |
227 |
} |
228 |
|
229 |
if (JavaIndex.getAttribute(sourceRoot, DIRTY_ROOT, null) != null) { |
230 |
return false; |
231 |
} |
232 |
|
233 |
FileObject[][] sources = new FileObject[1][]; |
234 |
|
235 |
if (!protectAgainstErrors(targetFolder, sources, context)) { |
236 |
return false; |
237 |
} |
238 |
|
239 |
File tagFile = new File(targetFolder, TAG_FILE_NAME); |
240 |
File tagUpdateResourcesFile = new File(targetFolder, TAG_UPDATE_RESOURCES); |
241 |
final boolean forceResourceCopy = copyResources && keepResourceUpToDate && !tagUpdateResourcesFile.exists(); |
242 |
final boolean cosActive = tagFile.exists(); |
243 |
if (cosActive && !forceResourceCopy) { |
244 |
return true; |
245 |
} |
246 |
|
247 |
if (!cosActive) { |
248 |
delete(targetFolder, false/*#161085: cleanCompletely*/); |
249 |
} |
250 |
|
251 |
if (!targetFolder.exists() && !targetFolder.mkdirs()) { |
252 |
throw new IOException("Cannot create destination folder: " + targetFolder.getAbsolutePath()); |
253 |
} |
254 |
|
255 |
sources(targetFolder, sources); |
256 |
|
257 |
for (int i = sources[0].length - 1; i>=0; i--) { |
258 |
final FileObject sr = sources[0][i]; |
259 |
if (!cosActive) { |
260 |
URL srURL = sr.toURL(); |
261 |
File index = JavaIndex.getClassFolder(srURL, true); |
262 |
|
263 |
if (index == null) { |
264 |
//#181992: (not nice) ignore the annotation processing target directory: |
265 |
if (srURL.equals(AnnotationProcessingQuery.getAnnotationProcessingOptions(sr).sourceOutputDirectory())) { |
266 |
continue; |
267 |
} |
268 |
|
269 |
return null; |
270 |
} |
271 |
|
272 |
copyRecursively(index, targetFolder); |
273 |
} |
274 |
|
275 |
if (copyResources) { |
276 |
Set<String> javaMimeTypes = COSSynchronizingIndexer.gatherJavaMimeTypes(); |
277 |
String[] javaMimeTypesArr = javaMimeTypes.toArray(new String[0]); |
278 |
|
279 |
copyRecursively(sr, targetFolder, javaMimeTypes, javaMimeTypesArr); |
280 |
} |
281 |
} |
282 |
|
283 |
if (!cosActive) { |
284 |
new FileOutputStream(tagFile).close(); |
285 |
} |
286 |
|
287 |
if (keepResourceUpToDate) |
288 |
new FileOutputStream(tagUpdateResourcesFile).close(); |
289 |
|
290 |
return true; |
291 |
} |
192 |
} |
292 |
|
193 |
|
293 |
@SuppressWarnings("deprecation") |
194 |
@SuppressWarnings("deprecation") |
294 |
public static Boolean clean(URL sourceRoot) throws IOException { |
195 |
public static Boolean clean(URL sourceRoot) throws IOException { |
295 |
File targetFolder = getTarget(sourceRoot); |
196 |
final CompileOnSaveAction a = CompileOnSaveActionQuery.getAction(sourceRoot); |
296 |
|
197 |
if (a != null) { |
297 |
if (targetFolder == null) { |
198 |
final CompileOnSaveAction.Context ctx = CompileOnSaveAction.Context.clean(sourceRoot); |
298 |
return null; |
199 |
return a.performAction(ctx); |
299 |
} |
200 |
} |
300 |
|
|
|
301 |
File tagFile = new File(targetFolder, TAG_FILE_NAME); |
302 |
|
303 |
if (!tagFile.exists()) { |
304 |
return null; |
305 |
} |
306 |
|
307 |
try { |
308 |
SourceUtils.waitScanFinished(); |
309 |
} catch (InterruptedException e) { |
310 |
//Not Important |
311 |
LOG.log(Level.FINE, null, e); |
312 |
return false; |
313 |
} |
314 |
|
315 |
delete(targetFolder, false); |
316 |
delete(tagFile, true); |
317 |
|
318 |
return null; |
201 |
return null; |
319 |
} |
202 |
} |
320 |
|
203 |
|
321 |
public static File getTargetFolder(URL sourceRoot) { |
204 |
public static boolean isUpdateClasses(URL sourceRoot) { |
322 |
File targetFolder = getTarget(sourceRoot); |
205 |
final CompileOnSaveAction a = CompileOnSaveActionQuery.getAction(sourceRoot); |
323 |
|
206 |
return a != null ? |
324 |
if (targetFolder == null) { |
207 |
a.isUpdateClasses(): |
325 |
return null; |
208 |
false; |
326 |
} |
|
|
327 |
|
328 |
if (!new File(targetFolder, TAG_FILE_NAME).exists()) { |
329 |
return null; |
330 |
} |
331 |
|
332 |
return targetFolder; |
333 |
} |
209 |
} |
334 |
|
210 |
|
335 |
public static boolean isUpdateResources(File targetFolder) { |
211 |
public static boolean isUpdateResources(URL srcRoot) { |
336 |
return targetFolder != null && new File(targetFolder, TAG_UPDATE_RESOURCES).exists(); |
212 |
final CompileOnSaveAction a = CompileOnSaveActionQuery.getAction(srcRoot); |
|
|
213 |
return a != null ? |
214 |
a.isUpdateResources(): |
215 |
false; |
337 |
} |
216 |
} |
338 |
|
217 |
|
339 |
public static void classCacheUpdated(URL sourceRoot, File cacheRoot, Iterable<File> deleted, Iterable<File> updated, boolean resource) { |
218 |
public static void classCacheUpdated(URL sourceRoot, File cacheRoot, Iterable<File> deleted, Iterable<File> updated, boolean resource) { |
340 |
if (!deleted.iterator().hasNext() && !updated.iterator().hasNext()) { |
219 |
final CompileOnSaveAction a = CompileOnSaveActionQuery.getAction(sourceRoot); |
341 |
return ; |
220 |
if (a != null) { |
342 |
} |
|
|
343 |
|
344 |
File targetFolder = getTargetFolder(sourceRoot); |
345 |
|
346 |
if (targetFolder == null) { |
347 |
return ; |
348 |
} |
349 |
|
350 |
if (resource && !isUpdateResources(targetFolder)) { |
351 |
return ; |
352 |
} |
353 |
|
354 |
List<File> updatedFiles = new LinkedList<File>(); |
355 |
|
356 |
for (File deletedFile : deleted) { |
357 |
final String relPath = relativizeFile(cacheRoot, deletedFile); |
358 |
if (relPath == null) { |
359 |
throw new IllegalArgumentException (String.format( |
360 |
"Deleted file: %s is not under cache root: %s, (normalized file: %s).", //NOI18N |
361 |
deletedFile.getAbsolutePath(), |
362 |
cacheRoot.getAbsolutePath(), |
363 |
FileUtil.normalizeFile(deletedFile).getAbsolutePath())); |
364 |
} |
365 |
File toDelete = resolveFile(targetFolder, relPath); |
366 |
|
367 |
toDelete.delete(); |
368 |
updatedFiles.add(toDelete); |
369 |
} |
370 |
|
371 |
for (File updatedFile : updated) { |
372 |
final String relPath = relativizeFile(cacheRoot, updatedFile); |
373 |
if (relPath == null) { |
374 |
throw new IllegalArgumentException (String.format( |
375 |
"Updated file: %s is not under cache root: %s, (normalized file: %s).", //NOI18N |
376 |
updatedFile.getAbsolutePath(), |
377 |
cacheRoot.getAbsolutePath(), |
378 |
FileUtil.normalizeFile(updatedFile).getAbsolutePath())); |
379 |
} |
380 |
File target = resolveFile(targetFolder, relPath); |
381 |
|
382 |
try { |
221 |
try { |
383 |
copyFile(updatedFile, target); |
222 |
final CompileOnSaveAction.Context ctx = CompileOnSaveAction.Context.update( |
384 |
updatedFiles.add(target); |
223 |
sourceRoot, |
|
|
224 |
resource, |
225 |
cacheRoot, |
226 |
updated, |
227 |
deleted, |
228 |
(updatedFiles) -> fire(sourceRoot, updatedFiles)); |
229 |
a.performAction(ctx); |
385 |
} catch (IOException ex) { |
230 |
} catch (IOException ex) { |
386 |
Exceptions.printStackTrace(ex); |
231 |
Exceptions.printStackTrace(ex); |
387 |
} |
232 |
} |
388 |
} |
233 |
} |
389 |
|
234 |
} |
390 |
if (updatedFiles.size() > 0) { |
235 |
|
|
|
236 |
private static void fire( |
237 |
@NonNull final URL sourceRoot, |
238 |
@NonNull final Iterable<File> updatedFiles) { |
239 |
if (updatedFiles.iterator().hasNext()) { |
391 |
Set<ArtifactsUpdated> listeners; |
240 |
Set<ArtifactsUpdated> listeners; |
392 |
|
|
|
393 |
synchronized (BuildArtifactMapperImpl.class) { |
241 |
synchronized (BuildArtifactMapperImpl.class) { |
394 |
listeners = source2Listener.get(sourceRoot); |
242 |
listeners = source2Listener.get(sourceRoot); |
395 |
|
|
|
396 |
if (listeners != null) { |
243 |
if (listeners != null) { |
397 |
listeners = new HashSet<ArtifactsUpdated>(listeners); |
244 |
listeners = new HashSet<>(listeners); |
398 |
} |
245 |
} |
399 |
} |
246 |
} |
400 |
|
|
|
401 |
if (listeners != null) { |
247 |
if (listeners != null) { |
402 |
for (ArtifactsUpdated listener : listeners) { |
248 |
for (ArtifactsUpdated listener : listeners) { |
403 |
listener.artifactsUpdated(updatedFiles); |
249 |
listener.artifactsUpdated(updatedFiles); |
Lines 405-411
Link Here
|
405 |
} |
251 |
} |
406 |
} |
252 |
} |
407 |
} |
253 |
} |
408 |
|
254 |
|
409 |
private static void copyFile(File updatedFile, File target) throws IOException { |
255 |
private static void copyFile(File updatedFile, File target) throws IOException { |
410 |
final File parent = target.getParentFile(); |
256 |
final File parent = target.getParentFile(); |
411 |
if (parent != null && !parent.exists()) { |
257 |
if (parent != null && !parent.exists()) { |
Lines 692-698
Link Here
|
692 |
return delegate; |
538 |
return delegate; |
693 |
} |
539 |
} |
694 |
|
540 |
|
695 |
File target = getTarget(owner.getURL()); |
541 |
File target = CompileOnSaveAction.Context.getTarget(owner.toURL()); |
696 |
File tagFile = FileUtil.normalizeFile(new File(target, TAG_FILE_NAME)); |
542 |
File tagFile = FileUtil.normalizeFile(new File(target, TAG_FILE_NAME)); |
697 |
|
543 |
|
698 |
synchronized(this) { |
544 |
synchronized(this) { |
Lines 713-722
Link Here
|
713 |
} |
559 |
} |
714 |
|
560 |
|
715 |
return result; |
561 |
return result; |
716 |
} |
562 |
} |
717 |
} catch (FileStateInvalidException ex) { |
|
|
718 |
Exceptions.printStackTrace(ex); |
719 |
return null; |
720 |
} finally { |
563 |
} finally { |
721 |
recursive.remove(); |
564 |
recursive.remove(); |
722 |
} |
565 |
} |
Lines 794-798
Link Here
|
794 |
} |
637 |
} |
795 |
}); |
638 |
}); |
796 |
} |
639 |
} |
|
|
640 |
} |
641 |
|
642 |
private static final class DefaultCompileOnSaveAction implements CompileOnSaveAction { |
643 |
private final URL root; |
644 |
|
645 |
DefaultCompileOnSaveAction(@NonNull final URL root) { |
646 |
this.root = root; |
647 |
} |
648 |
|
649 |
@Override |
650 |
public boolean isUpdateClasses() { |
651 |
return isUpdateClasses(CompileOnSaveAction.Context.getTarget(root)); |
652 |
} |
653 |
|
654 |
@Override |
655 |
public boolean isUpdateResources() { |
656 |
return isUpdateResources(CompileOnSaveAction.Context.getTarget(root)); |
657 |
} |
658 |
|
659 |
@Override |
660 |
public Boolean performAction(@NonNull final Context ctx) throws IOException { |
661 |
assert root.equals(ctx.getSourceRoot()); |
662 |
switch (ctx.getOperation()) { |
663 |
case CLEAN: |
664 |
return performClean(ctx); |
665 |
case SYNC: |
666 |
return performSync(ctx); |
667 |
case UPDATE: |
668 |
return performUpdate(ctx); |
669 |
default: |
670 |
} throw new IllegalArgumentException(String.valueOf(ctx.getOperation())); |
671 |
} |
672 |
|
673 |
private Boolean performClean(@NonNull final Context ctx) throws IOException { |
674 |
final File targetFolder = ctx.getTarget(); |
675 |
|
676 |
if (targetFolder == null) { |
677 |
return null; |
678 |
} |
679 |
|
680 |
File tagFile = new File(targetFolder, TAG_FILE_NAME); |
681 |
|
682 |
if (!tagFile.exists()) { |
683 |
return null; |
684 |
} |
685 |
|
686 |
try { |
687 |
SourceUtils.waitScanFinished(); |
688 |
} catch (InterruptedException e) { |
689 |
//Not Important |
690 |
LOG.log(Level.FINE, null, e); |
691 |
return false; |
692 |
} |
693 |
|
694 |
delete(targetFolder, false); |
695 |
delete(tagFile, true); |
696 |
|
697 |
return null; |
698 |
} |
699 |
|
700 |
private Boolean performSync(@NonNull final Context ctx) throws IOException { |
701 |
final URL sourceRoot = ctx.getSourceRoot(); |
702 |
final File targetFolder = ctx.getTarget(); |
703 |
final boolean copyResources = ctx.isCopyResources(); |
704 |
final boolean keepResourceUpToDate = ctx.isKeepResourcesUpToDate(); |
705 |
final Object context = ctx.getOwner(); |
706 |
|
707 |
if (targetFolder == null) { |
708 |
return null; |
709 |
} |
710 |
|
711 |
try { |
712 |
SourceUtils.waitScanFinished(); |
713 |
} catch (InterruptedException e) { |
714 |
//Not Important |
715 |
LOG.log(Level.FINE, null, e); |
716 |
return null; |
717 |
} |
718 |
|
719 |
if (JavaIndex.ensureAttributeValue(sourceRoot, DIRTY_ROOT, null)) { |
720 |
IndexingManager.getDefault().refreshIndexAndWait(sourceRoot, null); |
721 |
} |
722 |
|
723 |
if (JavaIndex.getAttribute(sourceRoot, DIRTY_ROOT, null) != null) { |
724 |
return false; |
725 |
} |
726 |
|
727 |
FileObject[][] sources = new FileObject[1][]; |
728 |
|
729 |
if (!protectAgainstErrors(targetFolder, sources, context)) { |
730 |
return false; |
731 |
} |
732 |
|
733 |
File tagFile = new File(targetFolder, TAG_FILE_NAME); |
734 |
File tagUpdateResourcesFile = new File(targetFolder, TAG_UPDATE_RESOURCES); |
735 |
final boolean forceResourceCopy = copyResources && keepResourceUpToDate && !tagUpdateResourcesFile.exists(); |
736 |
final boolean cosActive = tagFile.exists(); |
737 |
if (cosActive && !forceResourceCopy) { |
738 |
return true; |
739 |
} |
740 |
|
741 |
if (!cosActive) { |
742 |
delete(targetFolder, false/*#161085: cleanCompletely*/); |
743 |
} |
744 |
|
745 |
if (!targetFolder.exists() && !targetFolder.mkdirs()) { |
746 |
throw new IOException("Cannot create destination folder: " + targetFolder.getAbsolutePath()); |
747 |
} |
748 |
|
749 |
sources(targetFolder, sources); |
750 |
|
751 |
for (int i = sources[0].length - 1; i>=0; i--) { |
752 |
final FileObject sr = sources[0][i]; |
753 |
if (!cosActive) { |
754 |
URL srURL = sr.toURL(); |
755 |
File index = JavaIndex.getClassFolder(srURL, true); |
756 |
|
757 |
if (index == null) { |
758 |
//#181992: (not nice) ignore the annotation processing target directory: |
759 |
if (srURL.equals(AnnotationProcessingQuery.getAnnotationProcessingOptions(sr).sourceOutputDirectory())) { |
760 |
continue; |
761 |
} |
762 |
|
763 |
return null; |
764 |
} |
765 |
|
766 |
copyRecursively(index, targetFolder); |
767 |
} |
768 |
|
769 |
if (copyResources) { |
770 |
Set<String> javaMimeTypes = COSSynchronizingIndexer.gatherJavaMimeTypes(); |
771 |
String[] javaMimeTypesArr = javaMimeTypes.toArray(new String[0]); |
772 |
|
773 |
copyRecursively(sr, targetFolder, javaMimeTypes, javaMimeTypesArr); |
774 |
} |
775 |
} |
776 |
|
777 |
if (!cosActive) { |
778 |
new FileOutputStream(tagFile).close(); |
779 |
} |
780 |
|
781 |
if (keepResourceUpToDate) |
782 |
new FileOutputStream(tagUpdateResourcesFile).close(); |
783 |
|
784 |
return true; |
785 |
} |
786 |
|
787 |
private Boolean performUpdate(@NonNull final Context ctx) throws IOException { |
788 |
final Iterable<? extends File> deleted = ctx.getDeleted(); |
789 |
final Iterable<? extends File> updated = ctx.getUpdated(); |
790 |
final boolean resource = ctx.isCopyResources(); |
791 |
final File cacheRoot = ctx.getCacheRoot(); |
792 |
if (!deleted.iterator().hasNext() && !updated.iterator().hasNext()) { |
793 |
return null; |
794 |
} |
795 |
File targetFolder = ctx.getTarget(); |
796 |
if (targetFolder == null) { |
797 |
return null; |
798 |
} |
799 |
if (!isUpdateClasses(targetFolder)) { |
800 |
return null; |
801 |
} |
802 |
|
803 |
if (resource && !isUpdateResources(targetFolder)) { |
804 |
return null; |
805 |
} |
806 |
|
807 |
List<File> updatedFiles = new LinkedList<>(); |
808 |
|
809 |
for (File deletedFile : deleted) { |
810 |
final String relPath = relativizeFile(cacheRoot, deletedFile); |
811 |
if (relPath == null) { |
812 |
throw new IllegalArgumentException (String.format( |
813 |
"Deleted file: %s is not under cache root: %s, (normalized file: %s).", //NOI18N |
814 |
deletedFile.getAbsolutePath(), |
815 |
cacheRoot.getAbsolutePath(), |
816 |
FileUtil.normalizeFile(deletedFile).getAbsolutePath())); |
817 |
} |
818 |
File toDelete = resolveFile(targetFolder, relPath); |
819 |
|
820 |
toDelete.delete(); |
821 |
updatedFiles.add(toDelete); |
822 |
} |
823 |
|
824 |
for (File updatedFile : updated) { |
825 |
final String relPath = relativizeFile(cacheRoot, updatedFile); |
826 |
if (relPath == null) { |
827 |
throw new IllegalArgumentException (String.format( |
828 |
"Updated file: %s is not under cache root: %s, (normalized file: %s).", //NOI18N |
829 |
updatedFile.getAbsolutePath(), |
830 |
cacheRoot.getAbsolutePath(), |
831 |
FileUtil.normalizeFile(updatedFile).getAbsolutePath())); |
832 |
} |
833 |
File target = resolveFile(targetFolder, relPath); |
834 |
|
835 |
try { |
836 |
copyFile(updatedFile, target); |
837 |
updatedFiles.add(target); |
838 |
} catch (IOException ex) { |
839 |
Exceptions.printStackTrace(ex); |
840 |
} |
841 |
} |
842 |
ctx.filesUpdated(updatedFiles); |
843 |
return true; |
844 |
} |
845 |
|
846 |
private boolean isUpdateClasses(@NullAllowed final File targetFolder) { |
847 |
if (targetFolder == null) { |
848 |
return false; |
849 |
} |
850 |
return new File(targetFolder, TAG_FILE_NAME).exists(); |
851 |
} |
852 |
|
853 |
private boolean isUpdateResources(@NullAllowed final File targetFolder) { |
854 |
if (targetFolder == null) { |
855 |
return false; |
856 |
} |
857 |
return new File(targetFolder, TAG_UPDATE_RESOURCES).exists(); |
858 |
} |
859 |
} |
860 |
|
861 |
@ServiceProvider(service = CompileOnSaveAction.Provider.class, position = Integer.MAX_VALUE) |
862 |
public static final class Provider implements CompileOnSaveAction.Provider { |
863 |
@Override |
864 |
public CompileOnSaveAction forRoot(@NonNull final URL root) { |
865 |
return new DefaultCompileOnSaveAction(root); |
866 |
} |
797 |
} |
867 |
} |
798 |
} |
868 |
} |