@@ -0,0 +1,2518 @@
+import json%0Aimport os%0Aimport tempfile%0A%0Afrom lint.linter import Linter%0Afrom lint.util import communicate, memoize, which%0A%0Adef climb(top):%0A    right = True%0A    while right:%0A        top, right = os.path.split(top)%0A        yield top%0A%0A@memoize%0Adef find(top, filename):%0A    for d in climb(top):%0A        name = os.path.join(d, filename)%0A        if os.path.isfile(name):%0A            return d%0A%0Aclass Java(Linter):%0A    language = 'java'%0A    cmd = ('eclim', '-command', 'java_src_update')%0A    regex = r'.'%0A%0A    def communicate(self, cmd, code):%0A        if not which('eclim'):%0A            # if we can't find eclim in path%0A            # then we want safer behavior%0A%09    # in case nuking the file below is bad%0A            return%0A%0A        project = find(os.path.dirname(self.filename), '.project')%0A        filename = self.filename.replace(project, '', 1).lstrip(os.sep)%0A        project = os.path.basename(project)%0A%0A        # can't stdin or temp use file - hack time?%0A        # this *could* become a tmp directory%0A        # but I'd need to know all files to copy%0A        # from the source project%0A        tmp = tempfile.mktemp()%0A        os.rename(self.filename, tmp)%0A        # at least we get some inode protection on posix%0A        inode = None%0A%0A        with open(self.filename, 'wb') as f:%0A            f.write(code)%0A            if os.name == 'posix':%0A                inode = os.stat(self.filename).st_ino%0A%0A        try:%0A            cmd = cmd + ('-p', project, '-f', filename, '-v')%0A            output = communicate(cmd, '')%0A        finally:%0A            if inode is not None:%0A                new_inode = os.stat(self.filename).st_ino%0A                if new_inode != inode:%0A                    # they saved over our tmp file, bail%0A                    return output%0A%0A            os.unlink(self.filename)%0A            os.rename(tmp, self.filename)%0A%0A        return output%0A%0A    def find_errors(self, output):%0A        try:%0A            obj = json.loads(output)%0A            for item in obj:%0A                # TODO: highlight warnings in a different color?%0A                # warning = item%5B'warning'%5D%0A                line, col = item%5B'line'%5D-1, item%5B'column'%5D-1%0A                message = item%5B'message'%5D%0A                yield True, line, col, message, None%0A        except Exception:%0A            error = 'eclim error'%0A            if 'Connection refused' in output:%0A                error += ' Connection Refused'%0A            yield True, 0, None, error, None%0A            # maybe do this on line one?%0A            # yield %7B%22eclim_exception%22: str(e)%7D%0A

add eclim-based Java linting