diff --git a/project/dexter-core/src/java/com/samsung/sec/dexter/core/config/DexterConfig.java b/project/dexter-core/src/java/com/samsung/sec/dexter/core/config/DexterConfig.java index 22c414ce..59731b31 100644 --- a/project/dexter-core/src/java/com/samsung/sec/dexter/core/config/DexterConfig.java +++ b/project/dexter-core/src/java/com/samsung/sec/dexter/core/config/DexterConfig.java @@ -77,7 +77,7 @@ public class DexterConfig { public static final String FILTER_DELETE_FALSE_ALARM = "/api/v1/filter/delete-false-alarm"; public static final String GET_FALSE_ALARM_VERSION = "/api/v1/version/false-alarm"; public static final String POST_GLOBAL_DID = "/api/v1/defect/gid"; - public static final String DEFECT_DELETE = "/api/v1/defect/deleteAll"; + public static final String DEFECT_DELETE = "/api/v2/defect/deleteAll"; public static final String DEFECT_GROUP = "/api/v1/config/defect-group"; public static final String CODE = "/api/v1/config/code"; public static final String POST_SNAPSHOT_SOURCECODE = "/api/v1/analysis/snapshot/source"; diff --git a/project/dexter-eclipse/src/java/com/samsung/sec/dexter/eclipse/ARHandler.java b/project/dexter-eclipse/src/java/com/samsung/sec/dexter/eclipse/ARHandler.java index d4571152..893539a0 100644 --- a/project/dexter-eclipse/src/java/com/samsung/sec/dexter/eclipse/ARHandler.java +++ b/project/dexter-eclipse/src/java/com/samsung/sec/dexter/eclipse/ARHandler.java @@ -28,6 +28,7 @@ import java.util.List; import org.eclipse.core.resources.IFile; +import org.eclipse.swt.widgets.Display; import com.samsung.sec.dexter.core.analyzer.AnalysisResult; import com.samsung.sec.dexter.core.analyzer.EndOfAnalysisHandler; @@ -49,6 +50,20 @@ public ARHandler(final IFile file){ */ @Override public void handleAnalysisResult(final List resultList) { + if(Display.getCurrent() != null){ + addDefectMarkers(resultList); + return; + } + + Display.getDefault().asyncExec(new Runnable() { + @Override + public void run() { + addDefectMarkers(resultList); + } + }); + } + + private void addDefectMarkers(final List resultList) { DexterMarker.deleteMarkers(targetFile); List allDefectList = DexterAnalyzer.getAllDefectList(resultList); diff --git a/project/dexter-eclipse/src/java/com/samsung/sec/dexter/eclipse/DexterEclipseActivator.java b/project/dexter-eclipse/src/java/com/samsung/sec/dexter/eclipse/DexterEclipseActivator.java index d3936257..b7830c1d 100644 --- a/project/dexter-eclipse/src/java/com/samsung/sec/dexter/eclipse/DexterEclipseActivator.java +++ b/project/dexter-eclipse/src/java/com/samsung/sec/dexter/eclipse/DexterEclipseActivator.java @@ -41,6 +41,7 @@ import com.samsung.sec.dexter.core.config.DexterConfig; import com.samsung.sec.dexter.core.config.IDexterStandaloneListener; import com.samsung.sec.dexter.core.job.DexterJobFacade; +import com.samsung.sec.dexter.eclipse.builder.DexterResourceChangeHandler; import com.samsung.sec.dexter.eclipse.ui.login.LoginDialog; import com.samsung.sec.dexter.eclipse.ui.util.EclipseLog; import com.samsung.sec.dexter.eclipse.ui.util.EclipseUtil; @@ -100,6 +101,8 @@ public void start(BundleContext context) throws Exception { if (!DexterConfig.getInstance().isStandalone()) startLoginScheduler(); + + DexterResourceChangeHandler.start(); } private void startLoginScheduler() { diff --git a/project/dexter-eclipse/src/java/com/samsung/sec/dexter/eclipse/EclipseAnalysis.java b/project/dexter-eclipse/src/java/com/samsung/sec/dexter/eclipse/EclipseAnalysis.java index 0fbd3131..8a1fa18b 100644 --- a/project/dexter-eclipse/src/java/com/samsung/sec/dexter/eclipse/EclipseAnalysis.java +++ b/project/dexter-eclipse/src/java/com/samsung/sec/dexter/eclipse/EclipseAnalysis.java @@ -26,9 +26,12 @@ package com.samsung.sec.dexter.eclipse; import java.util.concurrent.ExecutionException; +import java.util.concurrent.TimeUnit; import org.eclipse.core.resources.IFile; +import org.eclipse.core.resources.IResource; +import com.google.common.base.Stopwatch; import com.google.common.cache.CacheLoader.InvalidCacheLoadException; import com.samsung.sec.dexter.core.analyzer.AnalysisConfig; import com.samsung.sec.dexter.core.analyzer.AnalysisEntityFactory; @@ -37,7 +40,10 @@ import com.samsung.sec.dexter.core.config.DexterConfig.LANGUAGE; import com.samsung.sec.dexter.core.exception.DexterException; import com.samsung.sec.dexter.core.exception.DexterRuntimeException; +import com.samsung.sec.dexter.core.plugin.DexterPluginManager; +import com.samsung.sec.dexter.core.util.DexterClient; import com.samsung.sec.dexter.core.util.DexterUtil; +import com.samsung.sec.dexter.eclipse.ui.util.EclipseUtil; import com.samsung.sec.dexter.executor.DexterAnalyzer; public class EclipseAnalysis { @@ -67,6 +73,45 @@ public static void analysis(final IFile file, final long snapshotId, final long } + public static void analysis(final IResource resource) { + // can analyze without login because there can be network problem. + if (DexterPluginManager.getInstance().getPluginList().size() < 1) { + return; + } + + final Stopwatch s = Stopwatch.createStarted(); + + final IFile file = (IFile) resource; + try { + EclipseAnalysis.analysis(file, -1, -1); + DexterEclipseActivator.LOG.info("Analysis Elapsed : " + s.elapsed(TimeUnit.MILLISECONDS) + " ms >> " + + file.getFullPath().toOSString()); + } catch (DexterException e) { + DexterEclipseActivator.LOG.error("Analysis Failed: " + file.getFullPath().toOSString() + " : " + e.getMessage(), e); + } + } + + public static void deleteDefect(final IResource resource){ + if (DexterPluginManager.getInstance().getPluginList().size() < 1) + return; + + if (DexterClient.getInstance().isServerAlive() == false) + return; + + final IFile file = (IFile) resource; + + try { + // TODO 다형성 적용할 것 + if (EclipseUtil.isValidJavaResource(resource)) { + DexterClient.getInstance().deleteDefects(DexterEclipseActivator.getJDTUtil().getModulePath(file), file.getName()); + } else if (EclipseUtil.isValidCAndCppResource(resource)) { + DexterClient.getInstance().deleteDefects(DexterEclipseActivator.getCDTUtil().getModulePath(file), file.getName()); + } + } catch (DexterRuntimeException e) { + DexterEclipseActivator.LOG.error(e.getMessage(), e); + } + } + /** * @param file * @return null if failing to load dexter-eclipse-jdt plugin diff --git a/project/dexter-eclipse/src/java/com/samsung/sec/dexter/eclipse/builder/DexterBuilder.java b/project/dexter-eclipse/src/java/com/samsung/sec/dexter/eclipse/builder/DexterBuilder.java index c8195faf..22060c98 100644 --- a/project/dexter-eclipse/src/java/com/samsung/sec/dexter/eclipse/builder/DexterBuilder.java +++ b/project/dexter-eclipse/src/java/com/samsung/sec/dexter/eclipse/builder/DexterBuilder.java @@ -26,30 +26,21 @@ package com.samsung.sec.dexter.eclipse.builder; import java.util.Map; -import java.util.concurrent.TimeUnit; -import org.eclipse.core.resources.IFile; import org.eclipse.core.resources.IProject; import org.eclipse.core.resources.IResource; import org.eclipse.core.resources.IResourceDelta; import org.eclipse.core.resources.IResourceDeltaVisitor; -import org.eclipse.core.resources.IResourceVisitor; import org.eclipse.core.resources.IncrementalProjectBuilder; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IProgressMonitor; -import com.google.common.base.Stopwatch; -import com.samsung.sec.dexter.core.exception.DexterException; -import com.samsung.sec.dexter.core.exception.DexterRuntimeException; -import com.samsung.sec.dexter.core.plugin.DexterPluginManager; -import com.samsung.sec.dexter.core.util.DexterClient; -import com.samsung.sec.dexter.core.util.DexterUtil; -import com.samsung.sec.dexter.eclipse.DexterEclipseActivator; import com.samsung.sec.dexter.eclipse.EclipseAnalysis; import com.samsung.sec.dexter.eclipse.ui.util.EclipseUtil; public class DexterBuilder extends IncrementalProjectBuilder{ - DexterDeltaVisitor dexterDeltaVisitor; + public static final String BUILDER_ID = "dexter-eclipse.dexterBuilder"; + private DexterDeltaVisitor dexterDeltaVisitor; public DexterBuilder(){ dexterDeltaVisitor = new DexterDeltaVisitor(); @@ -57,7 +48,7 @@ public DexterBuilder(){ class DexterDeltaVisitor implements IResourceDeltaVisitor { /* - * (non-Javadoc) + * return true to continue visiting children. * * @see * org.eclipse.core.resources.IResourceDeltaVisitor#visit(org.eclipse @@ -67,34 +58,33 @@ public boolean visit(IResourceDelta delta) throws CoreException { final IResource resource = delta.getResource(); switch (delta.getKind()) { - case IResourceDelta.ADDED: // handle added resource - case IResourceDelta.CHANGED: // handle changed resource - analysis(resource); - break; - case IResourceDelta.REMOVED: // handle removed resource - deleteDefect(resource); - break; -// case IResourceDelta.OPEN: -// break; + case IResourceDelta.ADDED: + case IResourceDelta.CHANGED: + analysis(resource); + break; + case IResourceDelta.REMOVED: + if (EclipseUtil.isValidJavaResource(resource)) { + EclipseAnalysis.deleteDefect(resource); + } + break; + case IResourceDelta.OPEN: + default: + break; } - // return true to continue visiting children. + return true; } } - - class JavaResourceVisitor implements IResourceVisitor { - public boolean visit(final IResource resource) { - analysis(resource); - - return true; + + private void analysis(final IResource resource) { + if (EclipseUtil.isValidJavaResource(resource) == false) { + return; } + + EclipseAnalysis.analysis(resource); } - public static final String BUILDER_ID = "dexter-eclipse.dexterBuilder"; - /* - * (non-Javadoc) - * * @see org.eclipse.core.internal.events.InternalBuilder#build(int, * java.util.Map, org.eclipse.core.runtime.IProgressMonitor) */ @@ -115,51 +105,6 @@ protected IProject[] build(int kind, @SuppressWarnings("rawtypes") Map args, IPr return new IProject[0]; } - void analysis(final IResource resource) { - // can analyze without login because there can be network problem. - if (DexterPluginManager.getInstance().getPluginList().size() < 1) { - return; - } - - if (EclipseUtil.isValidJavaResource(resource) || EclipseUtil.isValidCAndCppResource(resource)) { - final Stopwatch s = Stopwatch.createStarted(); - - final IFile file = (IFile) resource; - try { - EclipseAnalysis.analysis(file, -1, -1); - DexterEclipseActivator.LOG.info("Analysis Elapsed : " + s.elapsed(TimeUnit.MILLISECONDS) + " ms >> " - + file.getFullPath().toOSString()); - } catch (DexterException e) { - DexterEclipseActivator.LOG.error("Analysis Failed: " + file.getFullPath().toOSString() + " : " + e.getMessage(), e); - } - } - } - - private void deleteDefect(final IResource resource){ - if (DexterPluginManager.getInstance().getPluginList().size() < 1) { - return; - } - - if (!(resource instanceof IFile) || !resource.getName().endsWith(".java")) { - return; - } - - final IFile file = (IFile) resource; - - try { - // TODO 다형성 적용할 것 - if(resource.getName().endsWith(".java")){ - DexterClient.getInstance().deleteDefects(DexterEclipseActivator.getJDTUtil().getModulePath(file), file.getName()); - } else if(resource.getName().endsWith(".c") || resource.getName().endsWith(".h") - || resource.getName().endsWith(".cpp") || resource.getName().endsWith(".hpp")){ - DexterClient.getInstance().deleteDefects(DexterEclipseActivator.getCDTUtil().getModulePath(file), file.getName()); - } - } catch (DexterRuntimeException e) { - DexterEclipseActivator.LOG.error(e.getMessage(), e); - } - } - - protected void fullBuild(final IProgressMonitor monitor) throws CoreException { } diff --git a/project/dexter-eclipse/src/java/com/samsung/sec/dexter/eclipse/builder/DexterMarker.java b/project/dexter-eclipse/src/java/com/samsung/sec/dexter/eclipse/builder/DexterMarker.java index f6a9c759..ade28a16 100644 --- a/project/dexter-eclipse/src/java/com/samsung/sec/dexter/eclipse/builder/DexterMarker.java +++ b/project/dexter-eclipse/src/java/com/samsung/sec/dexter/eclipse/builder/DexterMarker.java @@ -28,7 +28,6 @@ import java.io.BufferedReader; import java.io.File; import java.io.FileInputStream; -import java.io.FileNotFoundException; import java.io.FileReader; import java.io.IOException; import java.io.InputStream; @@ -38,7 +37,6 @@ import org.eclipse.core.resources.IFile; import org.eclipse.core.resources.IMarker; import org.eclipse.core.resources.IResource; -import org.eclipse.core.runtime.CoreException; import com.google.common.base.Strings; import com.samsung.sec.dexter.core.analyzer.ResultFileConstant; diff --git a/project/dexter-eclipse/src/java/com/samsung/sec/dexter/eclipse/builder/DexterResourceChangeHandler.java b/project/dexter-eclipse/src/java/com/samsung/sec/dexter/eclipse/builder/DexterResourceChangeHandler.java new file mode 100644 index 00000000..02e928ea --- /dev/null +++ b/project/dexter-eclipse/src/java/com/samsung/sec/dexter/eclipse/builder/DexterResourceChangeHandler.java @@ -0,0 +1,110 @@ +/** + * Copyright (c) 2014 Samsung Electronics, Inc., + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ +package com.samsung.sec.dexter.eclipse.builder; + +import org.eclipse.core.resources.IMarkerDelta; +import org.eclipse.core.resources.IResourceChangeEvent; +import org.eclipse.core.resources.IResourceChangeListener; +import org.eclipse.core.resources.IResourceDelta; +import org.eclipse.core.resources.IResourceDeltaVisitor; +import org.eclipse.core.resources.ResourcesPlugin; +import org.eclipse.core.runtime.CoreException; + +import com.samsung.sec.dexter.eclipse.DexterEclipseActivator; +import com.samsung.sec.dexter.eclipse.EclipseAnalysis; +import com.samsung.sec.dexter.eclipse.ui.util.EclipseUtil; + +public class DexterResourceChangeHandler implements IResourceChangeListener{ + private static DexterResourceChangeHandler INSTANCE; + private static SourceFileChangeDeltaVisitor VISITOR; + + private DexterResourceChangeHandler() { + ResourcesPlugin.getWorkspace().addResourceChangeListener(this, IResourceChangeEvent.PRE_BUILD); + } + + public synchronized static DexterResourceChangeHandler start() { + if(INSTANCE == null){ + INSTANCE = new DexterResourceChangeHandler(); + VISITOR = new SourceFileChangeDeltaVisitor(); + } + + return INSTANCE; + } + + public synchronized static void shutdown(){ + if(INSTANCE != null && ResourcesPlugin.getWorkspace() != null){ + ResourcesPlugin.getWorkspace().removeResourceChangeListener(INSTANCE); + INSTANCE = null; + } + } + + @Override + public void resourceChanged(IResourceChangeEvent event) { + try { + event.getDelta().accept(VISITOR); + } catch (CoreException e) { + DexterEclipseActivator.LOG.error("Cannot analyze Source file because : " + e.getMessage(), e); + } + } + + static class SourceFileChangeDeltaVisitor implements IResourceDeltaVisitor{ + @Override + public boolean visit(IResourceDelta delta) throws CoreException { + // TODO : A static analysis plug-in should provide running environmental information either post-build or no-need-build + if (EclipseUtil.isValidCAndCppResource(delta.getResource()) == false) { + return true; + } + + switch(delta.getKind()){ + case IResourceDelta.REMOVED: + EclipseAnalysis.deleteDefect(delta.getResource()); + break; + case IResourceDelta.CHANGED: + analysis(delta); + break; + default: + // do nothing + } + + return true; + } + + private void analysis(IResourceDelta delta) { + boolean isDexterMarkerChanged = false; + + if(delta.getMarkerDeltas() != null){ + for(IMarkerDelta d : delta.getMarkerDeltas()){ + if(d.getType().contains("dexter")){ + isDexterMarkerChanged = true; + } + } + } + + if(isDexterMarkerChanged == false) + EclipseAnalysis.analysis(delta.getResource()); + } + } +} diff --git a/project/dexter-server/routes/analysis.js b/project/dexter-server/routes/analysis.js index 34cfe383..15763dc5 100644 --- a/project/dexter-server/routes/analysis.js +++ b/project/dexter-server/routes/analysis.js @@ -1485,7 +1485,7 @@ function updateAllCodeMetricsNoLast(){ function addFunctionMetrics(fileName, modulePath, userNo, snapshotId, functionMetric){ - // ϴ Ʈ + // �ϴ� ������Ʈ var sql = "UPDATE FunctionMetrics SET" + " lastYn = 'N' " + " WHERE " @@ -2271,7 +2271,7 @@ function updateDefect(defect, userNo, snapshotId, did) { function updateDefectV2(defect, userNo, snapshotId, did) { var sql = "UPDATE Defect SET " + " severityCode = " + database.toSqlValue(defect.severityCode) - + " , statusCode = CASE WHEN statusCode='FIX' THEN 'NEW' ELSE statusCode END" + + " , statusCode = CASE WHEN statusCode = 'EXC' THEN statusCode ELSE 'NEW' END" + " , message = " + database.toSqlValue(defect.message) + " , modifiedDateTime = now()" + " , modifierNo = " + userNo @@ -2405,19 +2405,15 @@ exports.deleteDefect = function(req, res) { var modulePath = req.body.modulePath; var fileName = req.body.fileName; - var userNo = req.currentUserId; + var userNo = account.getUserNo(req.currentUserId); var sql = "UPDATE Defect SET " + " statusCode = 'EFD'" + " , modifiedDateTime = now()" + " , modifierNo = " + userNo + " WHERE " - + " toolName = " + database.toSqlValue(defect.toolName) - + " and language = " + database.toSqlValue(defect.language) - + " and fileName = " + database.toSqlValue(defect.fileName) - + " and modulePath " + database.compareEqual(defect.modulePath) - + " and className " + database.compareEqual(defect.className) - + " and methodName " + database.compareEqual(defect.methodName); + + " fileName = " + database.toSqlValue(fileName) + + " and modulePath " + database.compareEqual(modulePath); database.exec(sql, function (err, result){ if(err){ diff --git a/project/dexter-server/server.js b/project/dexter-server/server.js index 9142508e..a5bdeef7 100644 --- a/project/dexter-server/server.js +++ b/project/dexter-server/server.js @@ -311,6 +311,7 @@ function initRestAPI(){ /* Defect */ app.post('/api/v1/defect/gid', auth, analysis.getGlobalDid); + app.post('/api/v1/defect/deleteAll', auth, analysis.deleteDefect); app.delete('/api/v1/defect/deleteAll', auth, analysis.deleteDefect); app.post('/api/v1/defect/dismiss', auth, analysis.changeDefectStatus); app.get('/api/v1/defect/moduleAndFile', auth, analysis.getModuleAndFileName); @@ -384,6 +385,7 @@ function initRestAPI(){ app.get('/api/v2/snapshot/showSnapshotDefectPage',analysis.getDefectListInSnapshotV2); app.get('/api/v2/defect/security', analysis.getDefectForSecurity); + app.post('/api/v2/defect/deleteAll', auth, analysis.deleteDefect); app.get('/api/v2/functionMetrics/', functionMetrics.getTotalFunctionMetrics); app.get('/api/v2/functionMetrics/All', functionMetrics.getAllFunctionMetrics);