From 2c3c66241fbed8fb6c4670e8cffe38ab1df902a5 Mon Sep 17 00:00:00 2001 From: Sebastian Sdorra Date: Sun, 12 Jun 2011 14:47:34 +0200 Subject: [PATCH 01/66] added api for repositorybrowser --- .../repository/AbstractRepositoryHandler.java | 15 ++ .../sonia/scm/repository/BrowserResult.java | 176 +++++++++++++ .../java/sonia/scm/repository/FileObject.java | 231 ++++++++++++++++++ .../scm/repository/RepositoryBrowser.java | 65 +++++ .../repository/RepositoryBrowserProvider.java | 56 +++++ .../scm/repository/RepositoryHandler.java | 3 +- .../scm/repository/RepositoryManager.java | 2 +- .../repository/xml/XmlRepositoryManager.java | 21 ++ 8 files changed, 567 insertions(+), 2 deletions(-) create mode 100644 scm-core/src/main/java/sonia/scm/repository/BrowserResult.java create mode 100644 scm-core/src/main/java/sonia/scm/repository/FileObject.java create mode 100644 scm-core/src/main/java/sonia/scm/repository/RepositoryBrowser.java create mode 100644 scm-core/src/main/java/sonia/scm/repository/RepositoryBrowserProvider.java diff --git a/scm-core/src/main/java/sonia/scm/repository/AbstractRepositoryHandler.java b/scm-core/src/main/java/sonia/scm/repository/AbstractRepositoryHandler.java index 5a6b70857b..b7b8282755 100644 --- a/scm-core/src/main/java/sonia/scm/repository/AbstractRepositoryHandler.java +++ b/scm-core/src/main/java/sonia/scm/repository/AbstractRepositoryHandler.java @@ -211,6 +211,21 @@ public abstract class AbstractRepositoryHandler +{ + + /** + * Method description + * + * + * @return + */ + @Override + public Iterator iterator() + { + Iterator iterator = null; + + if (children != null) + { + iterator = children.iterator(); + } + + return iterator; + } + + //~--- get methods ---------------------------------------------------------- + + /** + * Method description + * + * + * @return + */ + public List getChildren() + { + return children; + } + + /** + * Method description + * + * + * @return + */ + @Override + public Long getLastModified() + { + return lastModified; + } + + /** + * Method description + * + * + * @return + */ + public long getLength() + { + return length; + } + + /** + * Method description + * + * + * @return + */ + public String getName() + { + return name; + } + + /** + * Method description + * + * + * @return + */ + public String getPath() + { + return path; + } + + /** + * Method description + * + * + * @return + */ + public boolean isDirectory() + { + return directory; + } + + //~--- set methods ---------------------------------------------------------- + + /** + * Method description + * + * + * @param children + */ + public void setChildren(List children) + { + this.children = children; + } + + /** + * Method description + * + * + * @param directory + */ + public void setDirectory(boolean directory) + { + this.directory = directory; + } + + /** + * Method description + * + * + * @param lastModified + */ + public void setLastModified(Long lastModified) + { + this.lastModified = lastModified; + } + + /** + * Method description + * + * + * @param length + */ + public void setLength(long length) + { + this.length = length; + } + + /** + * Method description + * + * + * @param name + */ + public void setName(String name) + { + this.name = name; + } + + /** + * Method description + * + * + * @param path + */ + public void setPath(String path) + { + this.path = path; + } + + //~--- fields --------------------------------------------------------------- + + /** Field description */ + private List children; + + /** Field description */ + private boolean directory; + + /** Field description */ + private Long lastModified; + + /** Field description */ + private long length; + + /** Field description */ + private String name; + + /** Field description */ + private String path; +} diff --git a/scm-core/src/main/java/sonia/scm/repository/RepositoryBrowser.java b/scm-core/src/main/java/sonia/scm/repository/RepositoryBrowser.java new file mode 100644 index 0000000000..d103f12b1a --- /dev/null +++ b/scm-core/src/main/java/sonia/scm/repository/RepositoryBrowser.java @@ -0,0 +1,65 @@ +/** + * Copyright (c) 2010, Sebastian Sdorra + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of SCM-Manager; nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 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 REGENTS 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. + * + * http://bitbucket.org/sdorra/scm-manager + * + */ + + + +package sonia.scm.repository; + +//~--- JDK imports ------------------------------------------------------------ + +import java.io.IOException; + +/** + * + * @author Sebastian Sdorra + * @since 1.5 + */ +public interface RepositoryBrowser +{ + + /** + * Method description + * + * + * @param revision + * @param tag + * @param branch + * @param path + * + * @return + * + * @throws IOException + * @throws RepositoryException + */ + public BrowserResult getResult(String revision, String tag, String branch, + String path) + throws IOException, RepositoryException; +} diff --git a/scm-core/src/main/java/sonia/scm/repository/RepositoryBrowserProvider.java b/scm-core/src/main/java/sonia/scm/repository/RepositoryBrowserProvider.java new file mode 100644 index 0000000000..b87d3481d0 --- /dev/null +++ b/scm-core/src/main/java/sonia/scm/repository/RepositoryBrowserProvider.java @@ -0,0 +1,56 @@ +/** + * Copyright (c) 2010, Sebastian Sdorra + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of SCM-Manager; nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 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 REGENTS 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. + * + * http://bitbucket.org/sdorra/scm-manager + * + */ + + + +package sonia.scm.repository; + +/** + * + * @author Sebastian Sdorra + * @since 1.5 + */ +public interface RepositoryBrowserProvider +{ + + /** + * Method description + * + * + * @param repository + * + * @return null if RepositoryBrowser is not supported + * + * @throws RepositoryException + */ + public RepositoryBrowser getRepositoryBrowser(Repository repository) + throws RepositoryException; +} diff --git a/scm-core/src/main/java/sonia/scm/repository/RepositoryHandler.java b/scm-core/src/main/java/sonia/scm/repository/RepositoryHandler.java index e92bdd9acf..c9142d3b7e 100644 --- a/scm-core/src/main/java/sonia/scm/repository/RepositoryHandler.java +++ b/scm-core/src/main/java/sonia/scm/repository/RepositoryHandler.java @@ -47,7 +47,8 @@ import sonia.scm.plugin.ExtensionPoint; @ExtensionPoint public interface RepositoryHandler extends Handler, - ListenerSupport + ListenerSupport, + RepositoryBrowserProvider { /** diff --git a/scm-core/src/main/java/sonia/scm/repository/RepositoryManager.java b/scm-core/src/main/java/sonia/scm/repository/RepositoryManager.java index ee0621b7b7..9a81c26be6 100644 --- a/scm-core/src/main/java/sonia/scm/repository/RepositoryManager.java +++ b/scm-core/src/main/java/sonia/scm/repository/RepositoryManager.java @@ -49,7 +49,7 @@ import java.util.Collection; */ public interface RepositoryManager extends TypeManager, - ListenerSupport + ListenerSupport, RepositoryBrowserProvider { /** diff --git a/scm-webapp/src/main/java/sonia/scm/repository/xml/XmlRepositoryManager.java b/scm-webapp/src/main/java/sonia/scm/repository/xml/XmlRepositoryManager.java index 8df01ea38a..888eed97f8 100644 --- a/scm-webapp/src/main/java/sonia/scm/repository/xml/XmlRepositoryManager.java +++ b/scm-webapp/src/main/java/sonia/scm/repository/xml/XmlRepositoryManager.java @@ -52,6 +52,7 @@ import sonia.scm.repository.PermissionType; import sonia.scm.repository.PermissionUtil; import sonia.scm.repository.Repository; import sonia.scm.repository.RepositoryAllreadyExistExeption; +import sonia.scm.repository.RepositoryBrowser; import sonia.scm.repository.RepositoryException; import sonia.scm.repository.RepositoryHandler; import sonia.scm.repository.RepositoryHandlerNotFoundException; @@ -525,6 +526,26 @@ public class XmlRepositoryManager extends AbstractRepositoryManager return repositoryDB.getLastModified(); } + /** + * Method description + * + * + * @param repository + * + * @return + * + * @throws RepositoryException + */ + @Override + public RepositoryBrowser getRepositoryBrowser(Repository repository) + throws RepositoryException + { + AssertUtil.assertIsNotNull(repository); + isReader(repository); + + return getHandler(repository).getRepositoryBrowser(repository); + } + /** * Method description * From a20a673e4cf968abd30476d097bd058729b66088 Mon Sep 17 00:00:00 2001 From: Sebastian Sdorra Date: Sun, 12 Jun 2011 16:14:46 +0200 Subject: [PATCH 02/66] added hgbrowse.py for hg repositorybrowser --- .../src/main/resources/sonia/scm/hgbrowse.py | 84 +++++++++++++++++++ 1 file changed, 84 insertions(+) create mode 100644 plugins/scm-hg-plugin/src/main/resources/sonia/scm/hgbrowse.py diff --git a/plugins/scm-hg-plugin/src/main/resources/sonia/scm/hgbrowse.py b/plugins/scm-hg-plugin/src/main/resources/sonia/scm/hgbrowse.py new file mode 100644 index 0000000000..169da6eee6 --- /dev/null +++ b/plugins/scm-hg-plugin/src/main/resources/sonia/scm/hgbrowse.py @@ -0,0 +1,84 @@ +#!/usr/bin/env ${python} + +pythonPath = os.environ['SCM_PYTHON_PATH'] + +if len(pythonPath) > 0: + pathParts = pythonPath.split(os.pathsep) + for i in range(len(pathParts)): + sys.path.insert(i, pathParts[i]) + + +from mercurial import hg, ui +import datetime, time + +def getName(path): + parts = path.split('/') + length = len(parts) + if path.endswith('/'): + length =- 1 + return parts[length - 1] + +repositoryPath = os.environ['SCM_REPOSITORY_PATH'] + +revision = os.environ['SCM_REVISION'] +path = os.environ['SCM_PATH'] +name = getName(path) +length = 0 +paths = [] +repo = hg.repository(ui.ui(), path = repositoryPath) +mf = repo[revision].manifest() + +if path is "": + length = 1 + for f in mf: + paths.append(f) +else: + length = len(path.split('/')) + 1 + for f in mf: + if f.startswith(path): + paths.append(f) + +files = [] +directories = [] + +for p in paths: + parts = p.split('/') + depth = len(parts) + if depth is length: + file = repo[revision][p] + files.append(file) + elif depth > length: + dirpath = '' + for i in range(0, length): + dirpath += parts[i] + '/' + if not dirpath in directories: + directories.append(dirpath) + +print '' +print '' +print ' ' + revision + '' +# todo print tag, and branch +print ' ' +print ' ' + path + '' +print ' ' + name + '' +print ' true' +print ' ' +for dir in directories: + print ' ' + print ' ' + getName(dir) + '' + print ' ' + dir + '' + print ' true' + print ' ' + +for file in files: + print ' ' + print ' ' + getName(file.path()) + '' + print ' ' + file.path() + '' + print ' false' + print ' ' + str(file.size()) + '' + time = file.date()[0] + print ' ' + str(time).split('.')[0] + '' + print ' ' +print ' ' +print ' ' +print '' From e40b37d90b16be97f994be39436711a7eb5e87cb Mon Sep 17 00:00:00 2001 From: Sebastian Sdorra Date: Sun, 12 Jun 2011 16:16:30 +0200 Subject: [PATCH 03/66] simplify repositorybrowser api --- .../main/java/sonia/scm/repository/RepositoryBrowser.java | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/scm-core/src/main/java/sonia/scm/repository/RepositoryBrowser.java b/scm-core/src/main/java/sonia/scm/repository/RepositoryBrowser.java index d103f12b1a..b10460f507 100644 --- a/scm-core/src/main/java/sonia/scm/repository/RepositoryBrowser.java +++ b/scm-core/src/main/java/sonia/scm/repository/RepositoryBrowser.java @@ -50,8 +50,6 @@ public interface RepositoryBrowser * * * @param revision - * @param tag - * @param branch * @param path * * @return @@ -59,7 +57,6 @@ public interface RepositoryBrowser * @throws IOException * @throws RepositoryException */ - public BrowserResult getResult(String revision, String tag, String branch, - String path) + public BrowserResult getResult(String revision, String path) throws IOException, RepositoryException; } From b80af3ee4a6bd4fcb1aec93ff55328ceb42c956a Mon Sep 17 00:00:00 2001 From: Sebastian Sdorra Date: Sun, 12 Jun 2011 16:21:05 +0200 Subject: [PATCH 04/66] added missing import --- plugins/scm-hg-plugin/src/main/resources/sonia/scm/hgbrowse.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/plugins/scm-hg-plugin/src/main/resources/sonia/scm/hgbrowse.py b/plugins/scm-hg-plugin/src/main/resources/sonia/scm/hgbrowse.py index 169da6eee6..f2d37c1dd9 100644 --- a/plugins/scm-hg-plugin/src/main/resources/sonia/scm/hgbrowse.py +++ b/plugins/scm-hg-plugin/src/main/resources/sonia/scm/hgbrowse.py @@ -1,5 +1,7 @@ #!/usr/bin/env ${python} +import os + pythonPath = os.environ['SCM_PYTHON_PATH'] if len(pythonPath) > 0: From e7b959ac6c5e3a34ec15f7fac4fdbfe05ae326be Mon Sep 17 00:00:00 2001 From: Sebastian Sdorra Date: Sun, 12 Jun 2011 17:17:53 +0200 Subject: [PATCH 05/66] improve xml serialization --- .../src/main/java/sonia/scm/repository/FileObject.java | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/scm-core/src/main/java/sonia/scm/repository/FileObject.java b/scm-core/src/main/java/sonia/scm/repository/FileObject.java index 7122d1f9a1..10da857886 100644 --- a/scm-core/src/main/java/sonia/scm/repository/FileObject.java +++ b/scm-core/src/main/java/sonia/scm/repository/FileObject.java @@ -42,6 +42,10 @@ import sonia.scm.LastModifiedAware; import java.util.Iterator; import java.util.List; +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.XmlElementWrapper; import javax.xml.bind.annotation.XmlRootElement; /** @@ -50,6 +54,7 @@ import javax.xml.bind.annotation.XmlRootElement; * @since 1.5 */ @XmlRootElement(name = "file") +@XmlAccessorType(XmlAccessType.FIELD) public class FileObject implements LastModifiedAware, Iterable { @@ -212,6 +217,8 @@ public class FileObject implements LastModifiedAware, Iterable //~--- fields --------------------------------------------------------------- /** Field description */ + @XmlElement(name = "file") + @XmlElementWrapper(name = "children") private List children; /** Field description */ From 392f39de6732652c46b2295634475d2520020981 Mon Sep 17 00:00:00 2001 From: Sebastian Sdorra Date: Sun, 12 Jun 2011 17:19:23 +0200 Subject: [PATCH 06/66] implement mercurial repositorybrowser --- .../scm/repository/HgRepositoryBrowser.java | 185 ++++++++++++++++++ .../scm/repository/HgRepositoryHandler.java | 33 ++++ .../src/main/resources/sonia/scm/hgbrowse.py | 2 - 3 files changed, 218 insertions(+), 2 deletions(-) create mode 100644 plugins/scm-hg-plugin/src/main/java/sonia/scm/repository/HgRepositoryBrowser.java diff --git a/plugins/scm-hg-plugin/src/main/java/sonia/scm/repository/HgRepositoryBrowser.java b/plugins/scm-hg-plugin/src/main/java/sonia/scm/repository/HgRepositoryBrowser.java new file mode 100644 index 0000000000..094619c799 --- /dev/null +++ b/plugins/scm-hg-plugin/src/main/java/sonia/scm/repository/HgRepositoryBrowser.java @@ -0,0 +1,185 @@ +/** + * Copyright (c) 2010, Sebastian Sdorra + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of SCM-Manager; nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 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 REGENTS 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. + * + * http://bitbucket.org/sdorra/scm-manager + * + */ + + + +package sonia.scm.repository; + +//~--- non-JDK imports -------------------------------------------------------- + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import sonia.scm.util.IOUtil; +import sonia.scm.util.Util; + +//~--- JDK imports ------------------------------------------------------------ + +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; + +import java.util.Map; + +import javax.xml.bind.JAXBContext; +import javax.xml.bind.JAXBException; + +/** + * + * @author Sebastian Sdorra + */ +public class HgRepositoryBrowser implements RepositoryBrowser +{ + + /** Field description */ + public static final String DEFAULT_REVISION = "tip"; + + /** Field description */ + public static final String ENV_PATH = "SCM_PATH"; + + /** Field description */ + public static final String ENV_PYTHON_PATH = "SCM_PYTHON_PATH"; + + /** Field description */ + public static final String ENV_REPOSITORY_PATH = "SCM_REPOSITORY_PATH"; + + /** Field description */ + public static final String ENV_REVISION = "SCM_REVISION"; + + /** Field description */ + public static final String RESOURCE_BROWSE = "/sonia/scm/hgbrowse.py"; + + /** the logger for HgRepositoryBrowser */ + private static final Logger logger = + LoggerFactory.getLogger(HgRepositoryBrowser.class); + + //~--- constructors --------------------------------------------------------- + + /** + * Constructs ... + * + * + * @param handler + * @param repository + * @param browserResultContext + */ + public HgRepositoryBrowser(HgRepositoryHandler handler, + Repository repository, + JAXBContext browserResultContext) + { + this.handler = handler; + this.repository = repository; + this.browserResultContext = browserResultContext; + } + + //~--- get methods ---------------------------------------------------------- + + /** + * Method description + * + * + * @param revision + * @param path + * + * @return + * + * @throws IOException + * @throws RepositoryException + */ + @Override + public BrowserResult getResult(String revision, String path) + throws IOException, RepositoryException + { + HgConfig config = handler.getConfig(); + ProcessBuilder pb = new ProcessBuilder(config.getPythonBinary()); + Map env = pb.environment(); + + env.put(ENV_PYTHON_PATH, Util.nonNull(config.getPythonPath())); + + String directory = handler.getDirectory(repository).getAbsolutePath(); + + env.put(ENV_REPOSITORY_PATH, directory); + + if (Util.isEmpty(revision)) + { + revision = DEFAULT_REVISION; + } + + env.put(ENV_REVISION, revision); + env.put(ENV_PATH, Util.nonNull(path)); + + Process p = pb.start(); + BrowserResult result = null; + InputStream resource = null; + InputStream input = null; + OutputStream output = null; + + try + { + resource = HgRepositoryBrowser.class.getResourceAsStream(RESOURCE_BROWSE); + output = p.getOutputStream(); + IOUtil.copy(resource, output); + output.close(); + + // IOUtil.copy(p.getErrorStream(), System.err); + input = p.getInputStream(); + result = + (BrowserResult) browserResultContext.createUnmarshaller().unmarshal( + input); + + // IOUtil.copy(input, System.out); + input.close(); + } + catch (JAXBException ex) + { + logger.error("could not parse result", ex); + } + finally + { + IOUtil.close(resource); + IOUtil.close(input); + IOUtil.close(output); + } + + return result; + } + + //~--- fields --------------------------------------------------------------- + + /** Field description */ + private JAXBContext browserResultContext; + + /** Field description */ + private HgRepositoryHandler handler; + + /** Field description */ + private Repository repository; +} diff --git a/plugins/scm-hg-plugin/src/main/java/sonia/scm/repository/HgRepositoryHandler.java b/plugins/scm-hg-plugin/src/main/java/sonia/scm/repository/HgRepositoryHandler.java index dd5809e37f..15dd68db96 100644 --- a/plugins/scm-hg-plugin/src/main/java/sonia/scm/repository/HgRepositoryHandler.java +++ b/plugins/scm-hg-plugin/src/main/java/sonia/scm/repository/HgRepositoryHandler.java @@ -41,6 +41,7 @@ import com.google.inject.Singleton; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import sonia.scm.ConfigurationException; import sonia.scm.Type; import sonia.scm.installer.HgInstaller; import sonia.scm.installer.HgInstallerFactory; @@ -59,6 +60,10 @@ import sonia.scm.web.HgWebConfigWriter; import java.io.File; import java.io.IOException; + +import javax.xml.bind.JAXBContext; +import javax.xml.bind.JAXBException; + /** * * @author Sebastian Sdorra @@ -95,6 +100,15 @@ public class HgRepositoryHandler public HgRepositoryHandler(StoreFactory storeFactory, FileSystem fileSystem) { super(storeFactory, fileSystem); + + try + { + this.browserResultContext = JAXBContext.newInstance(BrowserResult.class); + } + catch (JAXBException ex) + { + throw new ConfigurationException("could not create jaxbcontext", ex); + } } //~--- methods -------------------------------------------------------------- @@ -181,6 +195,20 @@ public class HgRepositoryHandler return changesetViewer; } + /** + * Method description + * + * + * @param repository + * + * @return + */ + @Override + public RepositoryBrowser getRepositoryBrowser(Repository repository) + { + return new HgRepositoryBrowser(this, repository, browserResultContext); + } + /** * Method description * @@ -254,4 +282,9 @@ public class HgRepositoryHandler { return HgConfig.class; } + + //~--- fields --------------------------------------------------------------- + + /** Field description */ + private JAXBContext browserResultContext; } diff --git a/plugins/scm-hg-plugin/src/main/resources/sonia/scm/hgbrowse.py b/plugins/scm-hg-plugin/src/main/resources/sonia/scm/hgbrowse.py index f2d37c1dd9..84cf7c12b6 100644 --- a/plugins/scm-hg-plugin/src/main/resources/sonia/scm/hgbrowse.py +++ b/plugins/scm-hg-plugin/src/main/resources/sonia/scm/hgbrowse.py @@ -1,5 +1,3 @@ -#!/usr/bin/env ${python} - import os pythonPath = os.environ['SCM_PYTHON_PATH'] From a8f9692295d19393382c866689b82c059650f67a Mon Sep 17 00:00:00 2001 From: Sebastian Sdorra Date: Sun, 12 Jun 2011 18:15:13 +0200 Subject: [PATCH 07/66] added webservice method for repositorybrowser --- .../rest/resources/RepositoryResource.java | 70 +++++++++++++++++++ 1 file changed, 70 insertions(+) diff --git a/scm-webapp/src/main/java/sonia/scm/api/rest/resources/RepositoryResource.java b/scm-webapp/src/main/java/sonia/scm/api/rest/resources/RepositoryResource.java index 36a5add717..5bd379311d 100644 --- a/scm-webapp/src/main/java/sonia/scm/api/rest/resources/RepositoryResource.java +++ b/scm-webapp/src/main/java/sonia/scm/api/rest/resources/RepositoryResource.java @@ -39,7 +39,11 @@ import com.google.inject.Inject; import com.google.inject.Provider; import com.google.inject.Singleton; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + import sonia.scm.config.ScmConfiguration; +import sonia.scm.repository.BrowserResult; import sonia.scm.repository.Changeset; import sonia.scm.repository.ChangesetPagingResult; import sonia.scm.repository.ChangesetPreProcessor; @@ -48,6 +52,7 @@ import sonia.scm.repository.Permission; import sonia.scm.repository.PermissionType; import sonia.scm.repository.PermissionUtil; import sonia.scm.repository.Repository; +import sonia.scm.repository.RepositoryBrowser; import sonia.scm.repository.RepositoryException; import sonia.scm.repository.RepositoryHandler; import sonia.scm.repository.RepositoryManager; @@ -86,6 +91,10 @@ public class RepositoryResource /** Field description */ public static final String PATH_PART = "repositories"; + /** the logger for RepositoryResource */ + private static final Logger logger = + LoggerFactory.getLogger(RepositoryResource.class); + //~--- constructors --------------------------------------------------------- /** @@ -116,6 +125,67 @@ public class RepositoryResource //~--- get methods ---------------------------------------------------------- + /** + * Method description + * + * + * @param id + * @param revision + * @param path + * + * @return + */ + @GET + @Path("{id}/browse") + @Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON }) + public Response getBrowserResult(@PathParam("id") String id, + @QueryParam("revision") String revision, + @QueryParam("path") String path) + { + Response response = null; + Repository repository = repositoryManager.get(id); + + if (repository != null) + { + BrowserResult result = null; + + try + { + RepositoryBrowser browser = + repositoryManager.getRepositoryBrowser(repository); + + if (browser != null) + { + result = browser.getResult(revision, path); + } + else if (logger.isWarnEnabled()) + { + logger.warn("could not find repository browser for respository {}", + repository.getId()); + } + } + catch (Exception ex) + { + logger.error("could not retrive browserresult", ex); + } + + if (result != null) + { + response = Response.ok(result).build(); + } + else + { + response = Response.status(Response.Status.NOT_FOUND).build(); + } + } + else + { + response = Response.status(Response.Status.NOT_FOUND).build(); + } + + return response; + } + /** * Method description * From a9061d859290cd1dc2cb44aba18a08c7347f6033 Mon Sep 17 00:00:00 2001 From: Sebastian Sdorra Date: Mon, 13 Jun 2011 12:38:54 +0200 Subject: [PATCH 08/66] added sonia.repository.repositorybrowser.js --- scm-webapp/src/main/webapp/index.html | 1 + .../main/webapp/resources/images/document.gif | Bin 0 -> 237 bytes .../main/webapp/resources/images/folder.gif | Bin 0 -> 617 bytes .../sonia.repository.extendedinfopanel.js | 36 ++++- .../sonia.repository.repositorybrowser.js | 124 ++++++++++++++++++ 5 files changed, 160 insertions(+), 1 deletion(-) create mode 100644 scm-webapp/src/main/webapp/resources/images/document.gif create mode 100644 scm-webapp/src/main/webapp/resources/images/folder.gif create mode 100644 scm-webapp/src/main/webapp/resources/js/repository/sonia.repository.repositorybrowser.js diff --git a/scm-webapp/src/main/webapp/index.html b/scm-webapp/src/main/webapp/index.html index fcca2eaf60..0de37f789d 100644 --- a/scm-webapp/src/main/webapp/index.html +++ b/scm-webapp/src/main/webapp/index.html @@ -101,6 +101,7 @@ + diff --git a/scm-webapp/src/main/webapp/resources/images/document.gif b/scm-webapp/src/main/webapp/resources/images/document.gif new file mode 100644 index 0000000000000000000000000000000000000000..0c9e17f2b6165000dedf0668e99a8db6e4fac389 GIT binary patch literal 237 zcmZ?wbhEHb6krfwI3mmNcD=FFL2zkZoLd-nJ5-@bhL{Q2{z zZ{NPYfB$atmW^-UzWwy+w;w-# z+_YsQ&_D(-Q2fcl$iN`WpabH8>||igO1RFGk~zuuI52HaL}1|X4%z-r+2q;dTlS8;U(H{sMOf!AR*`}zUDxV%KLQ> loeYh2_+oSTrTBy;+eBkodV2eqtauqGPnkMdMplu*8UPy0fBgUe literal 0 HcmV?d00001 diff --git a/scm-webapp/src/main/webapp/resources/images/folder.gif b/scm-webapp/src/main/webapp/resources/images/folder.gif new file mode 100644 index 0000000000000000000000000000000000000000..a9aca8637902889bbd62e5077d9f55da543754d4 GIT binary patch literal 617 zcmV-v0+#(pNk%w1VGsZi0OooCG-aevgSwQr+<2qXdZg2BoX(lL-IBH2gM))MW~IK< z={07gtgNiy;NX&ylD^dH#Kgq2v$Ms;#gUPbHfN=gwcC-j+oYtVztrkAW~HjCs)w!D zUteG0;o&%FroPka$H&Lg-Ro^_ZFO~Zkh9v~-`|zD+?<@8g{#$@y4|_CxqN(lX=!P< z&*!Pc;y7odI%%a{U0ryFmqmE8larIKuCAe>p-+0TI%=oJ*zAjsljGy#czAfHr>8q= zr#Wb)x3{;Bve}NZ+O4gvvB~9;wA#MX>6W-jdu&}Usq|<1OyS=@=US3{=goL}hyPUe+xXr$KF|IB2D|wzjy>=b4$AgsatKV`DdG zr8j7%HfE%yrKO9o*?OhXMsuvh*X#fP{{R30000000000000000A^8LW004RbEC2ui z01yBW000NZfO>+1goSzx2#JYPJBETuV;~X`5Ka>fm?a%cf-4eOLsc3K6EqH|T@ivj zXbc)Xbr%;5Z7N=6CxRneYYD!-3&9Hj#5ZC<86OxJ56ueC&tMrM5erck78Ml-+}uYk z6f89qc>?C==S50$XK8df2J!L+CPH>@9&uE1Mk!5Z2S@~gvS9-fB5F9;VB;bTfrk(u zlKFxo#*-H)q!if5aU&BrJ~+JjVP$~HlP9y>xxz&Ti~ulW$_y|=iw', + + initComponent: function(){ + + var browserStore = new Sonia.rest.JsonStore({ + proxy: new Ext.data.HttpProxy({ + url: restUrl + 'repositories/' + this.repository.id + '/browse.json', + method: 'GET' + }), + fields: ['path', 'name', 'length', 'lastModified', 'directory'], + root: 'file.children', + idProperty: 'path', + autoLoad: true, + autoDestroy: true + }); + + var browserColModel = new Ext.grid.ColumnModel({ + defaults: { + sortable: false + }, + columns: [{ + id: 'icon', + dataIndex: 'directory', + header: '', + width: 28, + renderer: this.renderIcon, + scope: this + },{ + id: 'name', + dataIndex: 'name', + header: 'Name', + renderer: this.renderName, + scope: this + },{ + id: 'length', + dataIndex: 'length', + header: 'Length', + renderer: this.renderLength + },{ + id: 'lastModified', + dataIndex: 'lastModified', + header: 'LastModified', + renderer: Ext.util.Format.formatTimestamp + }] + }); + + var config = { + title: String.format(this.repositoryBrowserTitleText, this.repository.name), + store: browserStore, + colModel: browserColModel, + loadMask: true + }; + + Ext.apply(this, Ext.apply(this.initialConfig, config)); + Sonia.repository.RepositoryBrowser.superclass.initComponent.apply(this, arguments); + }, + + renderName: function(name, p, record){ + return name; + }, + + renderIcon: function(directory, p, record){ + var icon = null; + var name = record.data.name; + if ( directory ){ + icon = this.iconFolder; + } else { + icon = this.iconDocument; + } + return String.format(this.templateIcon, icon, name, name); + }, + + renderLength: function(length, p, record){ + var result = ''; + var directory = record.data.directory; + if ( ! directory ){ + result = Ext.util.Format.fileSize(length); + } + return result; + } + +}); + +// register xtype +Ext.reg('repositoryBrowser', Sonia.repository.RepositoryBrowser); From f8483c22afd351dc8e568d79bca85c195cd71d2e Mon Sep 17 00:00:00 2001 From: Sebastian Sdorra Date: Mon, 13 Jun 2011 13:14:25 +0200 Subject: [PATCH 09/66] added last commit message to repositorybrowser --- .../src/main/resources/sonia/scm/hgbrowse.py | 4 ++- .../java/sonia/scm/repository/FileObject.java | 25 +++++++++++++++++++ .../sonia.repository.repositorybrowser.js | 7 +++++- 3 files changed, 34 insertions(+), 2 deletions(-) diff --git a/plugins/scm-hg-plugin/src/main/resources/sonia/scm/hgbrowse.py b/plugins/scm-hg-plugin/src/main/resources/sonia/scm/hgbrowse.py index 84cf7c12b6..1c55af0917 100644 --- a/plugins/scm-hg-plugin/src/main/resources/sonia/scm/hgbrowse.py +++ b/plugins/scm-hg-plugin/src/main/resources/sonia/scm/hgbrowse.py @@ -71,13 +71,15 @@ for dir in directories: print ' ' for file in files: + time = file.date()[0] + desc = repo[file.linkrev()].description() print ' ' print ' ' + getName(file.path()) + '' print ' ' + file.path() + '' print ' false' print ' ' + str(file.size()) + '' - time = file.date()[0] print ' ' + str(time).split('.')[0] + '' + print ' ' + desc + '' print ' ' print ' ' print ' ' diff --git a/scm-core/src/main/java/sonia/scm/repository/FileObject.java b/scm-core/src/main/java/sonia/scm/repository/FileObject.java index 10da857886..cef6b7e372 100644 --- a/scm-core/src/main/java/sonia/scm/repository/FileObject.java +++ b/scm-core/src/main/java/sonia/scm/repository/FileObject.java @@ -90,6 +90,17 @@ public class FileObject implements LastModifiedAware, Iterable return children; } + /** + * Method description + * + * + * @return + */ + public String getDescription() + { + return description; + } + /** * Method description * @@ -159,6 +170,17 @@ public class FileObject implements LastModifiedAware, Iterable this.children = children; } + /** + * Method description + * + * + * @param description + */ + public void setDescription(String description) + { + this.description = description; + } + /** * Method description * @@ -221,6 +243,9 @@ public class FileObject implements LastModifiedAware, Iterable @XmlElementWrapper(name = "children") private List children; + /** Field description */ + private String description; + /** Field description */ private boolean directory; diff --git a/scm-webapp/src/main/webapp/resources/js/repository/sonia.repository.repositorybrowser.js b/scm-webapp/src/main/webapp/resources/js/repository/sonia.repository.repositorybrowser.js index 029cc88099..0092f1046c 100644 --- a/scm-webapp/src/main/webapp/resources/js/repository/sonia.repository.repositorybrowser.js +++ b/scm-webapp/src/main/webapp/resources/js/repository/sonia.repository.repositorybrowser.js @@ -46,7 +46,7 @@ Sonia.repository.RepositoryBrowser = Ext.extend(Ext.grid.GridPanel, { url: restUrl + 'repositories/' + this.repository.id + '/browse.json', method: 'GET' }), - fields: ['path', 'name', 'length', 'lastModified', 'directory'], + fields: ['path', 'name', 'length', 'lastModified', 'directory', 'description'], root: 'file.children', idProperty: 'path', autoLoad: true, @@ -80,10 +80,15 @@ Sonia.repository.RepositoryBrowser = Ext.extend(Ext.grid.GridPanel, { dataIndex: 'lastModified', header: 'LastModified', renderer: Ext.util.Format.formatTimestamp + },{ + id: 'description', + dataIndex: 'description', + header: 'Description' }] }); var config = { + autoExpandColumn: 'description', title: String.format(this.repositoryBrowserTitleText, this.repository.name), store: browserStore, colModel: browserColModel, From 9dc617852580d98e235d2d3ccf1a351e0ad36a5d Mon Sep 17 00:00:00 2001 From: Sebastian Sdorra Date: Mon, 13 Jun 2011 13:34:42 +0200 Subject: [PATCH 10/66] sort repositorybrowser files --- .../repository/FileObjectNameComparator.java | 86 +++++++++++++++++++ .../rest/resources/RepositoryResource.java | 26 ++++++ .../sonia.repository.repositorybrowser.js | 5 +- 3 files changed, 115 insertions(+), 2 deletions(-) create mode 100644 scm-core/src/main/java/sonia/scm/repository/FileObjectNameComparator.java diff --git a/scm-core/src/main/java/sonia/scm/repository/FileObjectNameComparator.java b/scm-core/src/main/java/sonia/scm/repository/FileObjectNameComparator.java new file mode 100644 index 0000000000..d059419830 --- /dev/null +++ b/scm-core/src/main/java/sonia/scm/repository/FileObjectNameComparator.java @@ -0,0 +1,86 @@ +/** + * Copyright (c) 2010, Sebastian Sdorra + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of SCM-Manager; nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 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 REGENTS 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. + * + * http://bitbucket.org/sdorra/scm-manager + * + */ + + + +package sonia.scm.repository; + +//~--- non-JDK imports -------------------------------------------------------- + +import sonia.scm.util.Util; + +//~--- JDK imports ------------------------------------------------------------ + +import java.util.Comparator; + +/** + * + * @author Sebastian Sdorra + */ +public class FileObjectNameComparator implements Comparator +{ + + /** Field description */ + public static FileObjectNameComparator instance = + new FileObjectNameComparator(); + + //~--- methods -------------------------------------------------------------- + + /** + * Method description + * + * + * @param o1 + * @param o2 + * + * @return + */ + @Override + public int compare(FileObject o1, FileObject o2) + { + int result = 0; + + if (o1.isDirectory() &&!o2.isDirectory()) + { + result = -1; + } + else if (!o1.isDirectory() && o2.isDirectory()) + { + result = 1; + } + else + { + result = Util.compare(o1.getName(), o2.getName()); + } + + return result; + } +} diff --git a/scm-webapp/src/main/java/sonia/scm/api/rest/resources/RepositoryResource.java b/scm-webapp/src/main/java/sonia/scm/api/rest/resources/RepositoryResource.java index 5bd379311d..e0c5928c3d 100644 --- a/scm-webapp/src/main/java/sonia/scm/api/rest/resources/RepositoryResource.java +++ b/scm-webapp/src/main/java/sonia/scm/api/rest/resources/RepositoryResource.java @@ -48,6 +48,8 @@ import sonia.scm.repository.Changeset; import sonia.scm.repository.ChangesetPagingResult; import sonia.scm.repository.ChangesetPreProcessor; import sonia.scm.repository.ChangesetViewer; +import sonia.scm.repository.FileObject; +import sonia.scm.repository.FileObjectNameComparator; import sonia.scm.repository.Permission; import sonia.scm.repository.PermissionType; import sonia.scm.repository.PermissionUtil; @@ -64,6 +66,8 @@ import sonia.scm.web.security.WebSecurityContext; import java.util.ArrayList; import java.util.Collection; +import java.util.Collections; +import java.util.List; import java.util.Set; import javax.servlet.http.HttpServletRequest; @@ -157,6 +161,7 @@ public class RepositoryResource if (browser != null) { result = browser.getResult(revision, path); + sort(result); } else if (logger.isWarnEnabled()) { @@ -394,6 +399,27 @@ public class RepositoryResource } } + /** + * Method description + * + * + * @param result + */ + private void sort(BrowserResult result) + { + FileObject file = result.getFile(); + + if (file != null) + { + List children = file.getChildren(); + + if (children != null) + { + Collections.sort(children, FileObjectNameComparator.instance); + } + } + } + //~--- get methods ---------------------------------------------------------- /** diff --git a/scm-webapp/src/main/webapp/resources/js/repository/sonia.repository.repositorybrowser.js b/scm-webapp/src/main/webapp/resources/js/repository/sonia.repository.repositorybrowser.js index 0092f1046c..833d923a5c 100644 --- a/scm-webapp/src/main/webapp/resources/js/repository/sonia.repository.repositorybrowser.js +++ b/scm-webapp/src/main/webapp/resources/js/repository/sonia.repository.repositorybrowser.js @@ -69,7 +69,8 @@ Sonia.repository.RepositoryBrowser = Ext.extend(Ext.grid.GridPanel, { dataIndex: 'name', header: 'Name', renderer: this.renderName, - scope: this + scope: this, + width: 180 },{ id: 'length', dataIndex: 'length', @@ -78,7 +79,7 @@ Sonia.repository.RepositoryBrowser = Ext.extend(Ext.grid.GridPanel, { },{ id: 'lastModified', dataIndex: 'lastModified', - header: 'LastModified', + header: 'Last Modified', renderer: Ext.util.Format.formatTimestamp },{ id: 'description', From df93637d529a7e45283d640659a433dbc9a584f7 Mon Sep 17 00:00:00 2001 From: Sebastian Sdorra Date: Mon, 13 Jun 2011 13:56:20 +0200 Subject: [PATCH 11/66] implement changedirectory method --- .../sonia.repository.repositorybrowser.js | 29 +++++++++++++++++-- 1 file changed, 27 insertions(+), 2 deletions(-) diff --git a/scm-webapp/src/main/webapp/resources/js/repository/sonia.repository.repositorybrowser.js b/scm-webapp/src/main/webapp/resources/js/repository/sonia.repository.repositorybrowser.js index 833d923a5c..8b6219e7f5 100644 --- a/scm-webapp/src/main/webapp/resources/js/repository/sonia.repository.repositorybrowser.js +++ b/scm-webapp/src/main/webapp/resources/js/repository/sonia.repository.repositorybrowser.js @@ -38,6 +38,7 @@ Sonia.repository.RepositoryBrowser = Ext.extend(Ext.grid.GridPanel, { iconFolder: 'resources/images/folder.gif', iconDocument: 'resources/images/document.gif', templateIcon: '{1}', + templateLink: '{0}', initComponent: function(){ @@ -93,15 +94,39 @@ Sonia.repository.RepositoryBrowser = Ext.extend(Ext.grid.GridPanel, { title: String.format(this.repositoryBrowserTitleText, this.repository.name), store: browserStore, colModel: browserColModel, - loadMask: true + loadMask: true, + listeners: { + click: { + fn: this.onClick, + scope: this + } + } }; Ext.apply(this, Ext.apply(this.initialConfig, config)); Sonia.repository.RepositoryBrowser.superclass.initComponent.apply(this, arguments); }, + onClick: function(e){ + var el = e.getTarget('.scm-browser'); + var path = el.rel; + if ( path.substr(-1) === '/' ){ + path = path.substr( 0, path.length - 1 ); + } + + if (debug){ + console.debug( 'change directory: ' + path ); + } + + this.getStore().load({ + params: { + path: path + } + }); + }, + renderName: function(name, p, record){ - return name; + return String.format(this.templateLink, name, record.data.path); }, renderIcon: function(directory, p, record){ From e921afce43e2dcf4d15b37d456fa20c77a71c479 Mon Sep 17 00:00:00 2001 From: Sebastian Sdorra Date: Mon, 13 Jun 2011 14:00:55 +0200 Subject: [PATCH 12/66] make repositorybrowser closeable --- .../js/repository/sonia.repository.extendedinfopanel.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/scm-webapp/src/main/webapp/resources/js/repository/sonia.repository.extendedinfopanel.js b/scm-webapp/src/main/webapp/resources/js/repository/sonia.repository.extendedinfopanel.js index bc094d7713..c558934169 100644 --- a/scm-webapp/src/main/webapp/resources/js/repository/sonia.repository.extendedinfopanel.js +++ b/scm-webapp/src/main/webapp/resources/js/repository/sonia.repository.extendedinfopanel.js @@ -82,7 +82,8 @@ Sonia.repository.ExtendedInfoPanel = Ext.extend(Sonia.repository.InfoPanel,{ return { id: 'repositorybrowser-' + this.item.id, xtype: 'repositoryBrowser', - repository: this.item + repository: this.item, + closable: true } }, From 0df1f147b8a45f94c9a80384ff548c124804d6e8 Mon Sep 17 00:00:00 2001 From: Sebastian Sdorra Date: Mon, 13 Jun 2011 14:07:21 +0200 Subject: [PATCH 13/66] only call changedirectory if the file is a directory --- .../sonia.repository.repositorybrowser.js | 23 +++++++++++++++++-- 1 file changed, 21 insertions(+), 2 deletions(-) diff --git a/scm-webapp/src/main/webapp/resources/js/repository/sonia.repository.repositorybrowser.js b/scm-webapp/src/main/webapp/resources/js/repository/sonia.repository.repositorybrowser.js index 8b6219e7f5..1da2f2d67b 100644 --- a/scm-webapp/src/main/webapp/resources/js/repository/sonia.repository.repositorybrowser.js +++ b/scm-webapp/src/main/webapp/resources/js/repository/sonia.repository.repositorybrowser.js @@ -109,7 +109,24 @@ Sonia.repository.RepositoryBrowser = Ext.extend(Ext.grid.GridPanel, { onClick: function(e){ var el = e.getTarget('.scm-browser'); - var path = el.rel; + + var rel = el.rel.split(':'); + var path = rel[1]; + + if ( rel[0] == 'dir' ){ + this.changeDirectory(path); + } else { + this.openFile(path); + } + }, + + openFile: function(path){ + if ( debug ){ + console.debug( 'open file: ' + path ); + } + }, + + changeDirectory: function(path){ if ( path.substr(-1) === '/' ){ path = path.substr( 0, path.length - 1 ); } @@ -126,7 +143,9 @@ Sonia.repository.RepositoryBrowser = Ext.extend(Ext.grid.GridPanel, { }, renderName: function(name, p, record){ - return String.format(this.templateLink, name, record.data.path); + var path = record.data.directory ? 'dir:' : 'file:'; + path += record.data.path; + return String.format(this.templateLink, name, path); }, renderIcon: function(directory, p, record){ From ec518faa7da62cfe71de945c15980cac97083acb Mon Sep 17 00:00:00 2001 From: Sebastian Sdorra Date: Mon, 13 Jun 2011 14:39:56 +0200 Subject: [PATCH 14/66] added back button to repositorybrowser --- .../sonia.repository.repositorybrowser.js | 55 ++++++++++++++++--- 1 file changed, 48 insertions(+), 7 deletions(-) diff --git a/scm-webapp/src/main/webapp/resources/js/repository/sonia.repository.repositorybrowser.js b/scm-webapp/src/main/webapp/resources/js/repository/sonia.repository.repositorybrowser.js index 1da2f2d67b..9ab90e9fa5 100644 --- a/scm-webapp/src/main/webapp/resources/js/repository/sonia.repository.repositorybrowser.js +++ b/scm-webapp/src/main/webapp/resources/js/repository/sonia.repository.repositorybrowser.js @@ -51,7 +51,13 @@ Sonia.repository.RepositoryBrowser = Ext.extend(Ext.grid.GridPanel, { root: 'file.children', idProperty: 'path', autoLoad: true, - autoDestroy: true + autoDestroy: true, + listeners: { + load: { + fn: this.loadStore, + scope: this + } + } }); var browserColModel = new Ext.grid.ColumnModel({ @@ -107,16 +113,51 @@ Sonia.repository.RepositoryBrowser = Ext.extend(Ext.grid.GridPanel, { Sonia.repository.RepositoryBrowser.superclass.initComponent.apply(this, arguments); }, + loadStore: function(store, records, extra){ + var path = extra.params.path; + if ( path != null && path.length > 0 ){ + + var index = path.lastIndexOf('/'); + if ( index > 0 ){ + path = path.substr(0, index); + } else { + path = ''; + } + + var File = Ext.data.Record.create([{ + name: 'name' + },{ + name: 'path' + },{ + name: 'directory' + },{ + name: 'length' + },{ + name: 'lastModified' + }]); + + store.insert(0, new File({ + name: '..', + path: path, + directory: true, + length: 0 + })); + } + }, + onClick: function(e){ var el = e.getTarget('.scm-browser'); - var rel = el.rel.split(':'); - var path = rel[1]; + if ( el != null ){ - if ( rel[0] == 'dir' ){ - this.changeDirectory(path); - } else { - this.openFile(path); + var rel = el.rel.split(':'); + var path = rel[1]; + + if ( rel[0] == 'dir' ){ + this.changeDirectory(path); + } else { + this.openFile(path); + } } }, From b98225955b7daed629b940458257dd95c3e72db9 Mon Sep 17 00:00:00 2001 From: Sebastian Sdorra Date: Mon, 13 Jun 2011 14:53:34 +0200 Subject: [PATCH 15/66] added syntaxhighlighter --- .../sonia.repository.repositorybrowser.js | 18 +- .../syntaxhighlighter/scripts/shAutoloader.js | 17 + .../syntaxhighlighter/scripts/shBrushAS3.js | 59 + .../scripts/shBrushAppleScript.js | 75 + .../syntaxhighlighter/scripts/shBrushBash.js | 59 + .../scripts/shBrushCSharp.js | 65 + .../scripts/shBrushColdFusion.js | 100 + .../syntaxhighlighter/scripts/shBrushCpp.js | 97 + .../syntaxhighlighter/scripts/shBrushCss.js | 91 + .../scripts/shBrushDelphi.js | 55 + .../syntaxhighlighter/scripts/shBrushDiff.js | 41 + .../scripts/shBrushErlang.js | 52 + .../scripts/shBrushGroovy.js | 67 + .../scripts/shBrushJScript.js | 52 + .../syntaxhighlighter/scripts/shBrushJava.js | 57 + .../scripts/shBrushJavaFX.js | 58 + .../syntaxhighlighter/scripts/shBrushPerl.js | 72 + .../syntaxhighlighter/scripts/shBrushPhp.js | 88 + .../syntaxhighlighter/scripts/shBrushPlain.js | 33 + .../scripts/shBrushPowerShell.js | 74 + .../scripts/shBrushPython.js | 64 + .../syntaxhighlighter/scripts/shBrushRuby.js | 55 + .../syntaxhighlighter/scripts/shBrushSass.js | 94 + .../syntaxhighlighter/scripts/shBrushScala.js | 51 + .../syntaxhighlighter/scripts/shBrushSql.js | 66 + .../syntaxhighlighter/scripts/shBrushVb.js | 56 + .../syntaxhighlighter/scripts/shBrushXml.js | 69 + .../syntaxhighlighter/scripts/shCore.js | 17 + .../syntaxhighlighter/scripts/shLegacy.js | 17 + .../syntaxhighlighter/src/shAutoloader.js | 130 ++ .../resources/syntaxhighlighter/src/shCore.js | 1721 +++++++++++++++++ .../syntaxhighlighter/src/shLegacy.js | 157 ++ .../syntaxhighlighter/styles/shCore.css | 226 +++ .../styles/shCoreDefault.css | 328 ++++ .../syntaxhighlighter/styles/shCoreDjango.css | 331 ++++ .../styles/shCoreEclipse.css | 339 ++++ .../syntaxhighlighter/styles/shCoreEmacs.css | 324 ++++ .../styles/shCoreFadeToGrey.css | 328 ++++ .../styles/shCoreMDUltra.css | 324 ++++ .../styles/shCoreMidnight.css | 324 ++++ .../syntaxhighlighter/styles/shCoreRDark.css | 324 ++++ .../styles/shThemeDefault.css | 117 ++ .../styles/shThemeDjango.css | 120 ++ .../styles/shThemeEclipse.css | 128 ++ .../syntaxhighlighter/styles/shThemeEmacs.css | 113 ++ .../styles/shThemeFadeToGrey.css | 117 ++ .../styles/shThemeMDUltra.css | 113 ++ .../styles/shThemeMidnight.css | 113 ++ .../syntaxhighlighter/styles/shThemeRDark.css | 113 ++ 49 files changed, 7500 insertions(+), 9 deletions(-) create mode 100644 scm-webapp/src/main/webapp/resources/syntaxhighlighter/scripts/shAutoloader.js create mode 100644 scm-webapp/src/main/webapp/resources/syntaxhighlighter/scripts/shBrushAS3.js create mode 100644 scm-webapp/src/main/webapp/resources/syntaxhighlighter/scripts/shBrushAppleScript.js create mode 100644 scm-webapp/src/main/webapp/resources/syntaxhighlighter/scripts/shBrushBash.js create mode 100644 scm-webapp/src/main/webapp/resources/syntaxhighlighter/scripts/shBrushCSharp.js create mode 100644 scm-webapp/src/main/webapp/resources/syntaxhighlighter/scripts/shBrushColdFusion.js create mode 100644 scm-webapp/src/main/webapp/resources/syntaxhighlighter/scripts/shBrushCpp.js create mode 100644 scm-webapp/src/main/webapp/resources/syntaxhighlighter/scripts/shBrushCss.js create mode 100644 scm-webapp/src/main/webapp/resources/syntaxhighlighter/scripts/shBrushDelphi.js create mode 100644 scm-webapp/src/main/webapp/resources/syntaxhighlighter/scripts/shBrushDiff.js create mode 100644 scm-webapp/src/main/webapp/resources/syntaxhighlighter/scripts/shBrushErlang.js create mode 100644 scm-webapp/src/main/webapp/resources/syntaxhighlighter/scripts/shBrushGroovy.js create mode 100644 scm-webapp/src/main/webapp/resources/syntaxhighlighter/scripts/shBrushJScript.js create mode 100644 scm-webapp/src/main/webapp/resources/syntaxhighlighter/scripts/shBrushJava.js create mode 100644 scm-webapp/src/main/webapp/resources/syntaxhighlighter/scripts/shBrushJavaFX.js create mode 100644 scm-webapp/src/main/webapp/resources/syntaxhighlighter/scripts/shBrushPerl.js create mode 100644 scm-webapp/src/main/webapp/resources/syntaxhighlighter/scripts/shBrushPhp.js create mode 100644 scm-webapp/src/main/webapp/resources/syntaxhighlighter/scripts/shBrushPlain.js create mode 100644 scm-webapp/src/main/webapp/resources/syntaxhighlighter/scripts/shBrushPowerShell.js create mode 100644 scm-webapp/src/main/webapp/resources/syntaxhighlighter/scripts/shBrushPython.js create mode 100644 scm-webapp/src/main/webapp/resources/syntaxhighlighter/scripts/shBrushRuby.js create mode 100644 scm-webapp/src/main/webapp/resources/syntaxhighlighter/scripts/shBrushSass.js create mode 100644 scm-webapp/src/main/webapp/resources/syntaxhighlighter/scripts/shBrushScala.js create mode 100644 scm-webapp/src/main/webapp/resources/syntaxhighlighter/scripts/shBrushSql.js create mode 100644 scm-webapp/src/main/webapp/resources/syntaxhighlighter/scripts/shBrushVb.js create mode 100644 scm-webapp/src/main/webapp/resources/syntaxhighlighter/scripts/shBrushXml.js create mode 100644 scm-webapp/src/main/webapp/resources/syntaxhighlighter/scripts/shCore.js create mode 100644 scm-webapp/src/main/webapp/resources/syntaxhighlighter/scripts/shLegacy.js create mode 100644 scm-webapp/src/main/webapp/resources/syntaxhighlighter/src/shAutoloader.js create mode 100644 scm-webapp/src/main/webapp/resources/syntaxhighlighter/src/shCore.js create mode 100644 scm-webapp/src/main/webapp/resources/syntaxhighlighter/src/shLegacy.js create mode 100644 scm-webapp/src/main/webapp/resources/syntaxhighlighter/styles/shCore.css create mode 100644 scm-webapp/src/main/webapp/resources/syntaxhighlighter/styles/shCoreDefault.css create mode 100644 scm-webapp/src/main/webapp/resources/syntaxhighlighter/styles/shCoreDjango.css create mode 100644 scm-webapp/src/main/webapp/resources/syntaxhighlighter/styles/shCoreEclipse.css create mode 100644 scm-webapp/src/main/webapp/resources/syntaxhighlighter/styles/shCoreEmacs.css create mode 100644 scm-webapp/src/main/webapp/resources/syntaxhighlighter/styles/shCoreFadeToGrey.css create mode 100644 scm-webapp/src/main/webapp/resources/syntaxhighlighter/styles/shCoreMDUltra.css create mode 100644 scm-webapp/src/main/webapp/resources/syntaxhighlighter/styles/shCoreMidnight.css create mode 100644 scm-webapp/src/main/webapp/resources/syntaxhighlighter/styles/shCoreRDark.css create mode 100644 scm-webapp/src/main/webapp/resources/syntaxhighlighter/styles/shThemeDefault.css create mode 100644 scm-webapp/src/main/webapp/resources/syntaxhighlighter/styles/shThemeDjango.css create mode 100644 scm-webapp/src/main/webapp/resources/syntaxhighlighter/styles/shThemeEclipse.css create mode 100644 scm-webapp/src/main/webapp/resources/syntaxhighlighter/styles/shThemeEmacs.css create mode 100644 scm-webapp/src/main/webapp/resources/syntaxhighlighter/styles/shThemeFadeToGrey.css create mode 100755 scm-webapp/src/main/webapp/resources/syntaxhighlighter/styles/shThemeMDUltra.css create mode 100644 scm-webapp/src/main/webapp/resources/syntaxhighlighter/styles/shThemeMidnight.css create mode 100644 scm-webapp/src/main/webapp/resources/syntaxhighlighter/styles/shThemeRDark.css diff --git a/scm-webapp/src/main/webapp/resources/js/repository/sonia.repository.repositorybrowser.js b/scm-webapp/src/main/webapp/resources/js/repository/sonia.repository.repositorybrowser.js index 9ab90e9fa5..8b898bd851 100644 --- a/scm-webapp/src/main/webapp/resources/js/repository/sonia.repository.repositorybrowser.js +++ b/scm-webapp/src/main/webapp/resources/js/repository/sonia.repository.repositorybrowser.js @@ -125,15 +125,15 @@ Sonia.repository.RepositoryBrowser = Ext.extend(Ext.grid.GridPanel, { } var File = Ext.data.Record.create([{ - name: 'name' - },{ - name: 'path' - },{ - name: 'directory' - },{ - name: 'length' - },{ - name: 'lastModified' + name: 'name' + },{ + name: 'path' + },{ + name: 'directory' + },{ + name: 'length' + },{ + name: 'lastModified' }]); store.insert(0, new File({ diff --git a/scm-webapp/src/main/webapp/resources/syntaxhighlighter/scripts/shAutoloader.js b/scm-webapp/src/main/webapp/resources/syntaxhighlighter/scripts/shAutoloader.js new file mode 100644 index 0000000000..4e29bddecb --- /dev/null +++ b/scm-webapp/src/main/webapp/resources/syntaxhighlighter/scripts/shAutoloader.js @@ -0,0 +1,17 @@ +/** + * SyntaxHighlighter + * http://alexgorbatchev.com/SyntaxHighlighter + * + * SyntaxHighlighter is donationware. If you are using it, please donate. + * http://alexgorbatchev.com/SyntaxHighlighter/donate.html + * + * @version + * 3.0.83 (July 02 2010) + * + * @copyright + * Copyright (C) 2004-2010 Alex Gorbatchev. + * + * @license + * Dual licensed under the MIT and GPL licenses. + */ +eval(function(p,a,c,k,e,d){e=function(c){return(c35?String.fromCharCode(c+29):c.toString(36))};if(!''.replace(/^/,String)){while(c--){d[e(c)]=k[c]||e(c)}k=[function(e){return d[e]}];e=function(){return'\\w+'};c=1};while(c--){if(k[c]){p=p.replace(new RegExp('\\b'+e(c)+'\\b','g'),k[c])}}return p}('(2(){1 h=5;h.I=2(){2 n(c,a){4(1 d=0;d|<|≥|>=|≤|<=|\*|\+|-|\/|÷|\^)/g, + css: 'color2' }, + + { regex: /\b(?:and|as|div|mod|not|or|return(?!\s&)(ing)?|equals|(is(n't| not)? )?equal( to)?|does(n't| not) equal|(is(n't| not)? )?(greater|less) than( or equal( to)?)?|(comes|does(n't| not) come) (after|before)|is(n't| not)?( in)? (back|front) of|is(n't| not)? behind|is(n't| not)?( (in|contained by))?|does(n't| not) contain|contain(s)?|(start|begin|end)(s)? with|((but|end) )?(consider|ignor)ing|prop(erty)?|(a )?ref(erence)?( to)?|repeat (until|while|with)|((end|exit) )?repeat|((else|end) )?if|else|(end )?(script|tell|try)|(on )?error|(put )?into|(of )?(it|me)|its|my|with (timeout( of)?|transaction)|end (timeout|transaction))\b/g, + css: 'keyword' }, + + { regex: /\b\d+(st|nd|rd|th)\b/g, // ordinals + css: 'keyword' }, + + { regex: /\b(?:about|above|against|around|at|below|beneath|beside|between|by|(apart|aside) from|(instead|out) of|into|on(to)?|over|since|thr(ough|u)|under)\b/g, + css: 'color3' }, + + { regex: /\b(?:adding folder items to|after receiving|choose( ((remote )?application|color|folder|from list|URL))?|clipboard info|set the clipboard to|(the )?clipboard|entire contents|display(ing| (alert|dialog|mode))?|document( (edited|file|nib name))?|file( (name|type))?|(info )?for|giving up after|(name )?extension|quoted form|return(ed)?|second(?! item)(s)?|list (disks|folder)|text item(s| delimiters)?|(Unicode )?text|(disk )?item(s)?|((current|list) )?view|((container|key) )?window|with (data|icon( (caution|note|stop))?|parameter(s)?|prompt|properties|seed|title)|case|diacriticals|hyphens|numeric strings|punctuation|white space|folder creation|application(s( folder)?| (processes|scripts position|support))?|((desktop )?(pictures )?|(documents|downloads|favorites|home|keychain|library|movies|music|public|scripts|sites|system|users|utilities|workflows) )folder|desktop|Folder Action scripts|font(s| panel)?|help|internet plugins|modem scripts|(system )?preferences|printer descriptions|scripting (additions|components)|shared (documents|libraries)|startup (disk|items)|temporary items|trash|on server|in AppleTalk zone|((as|long|short) )?user name|user (ID|locale)|(with )?password|in (bundle( with identifier)?|directory)|(close|open for) access|read|write( permission)?|(g|s)et eof|using( delimiters)?|starting at|default (answer|button|color|country code|entr(y|ies)|identifiers|items|name|location|script editor)|hidden( answer)?|open(ed| (location|untitled))?|error (handling|reporting)|(do( shell)?|load|run|store) script|administrator privileges|altering line endings|get volume settings|(alert|boot|input|mount|output|set) volume|output muted|(fax|random )?number|round(ing)?|up|down|toward zero|to nearest|as taught in school|system (attribute|info)|((AppleScript( Studio)?|system) )?version|(home )?directory|(IPv4|primary Ethernet) address|CPU (type|speed)|physical memory|time (stamp|to GMT)|replacing|ASCII (character|number)|localized string|from table|offset|summarize|beep|delay|say|(empty|multiple) selections allowed|(of|preferred) type|invisibles|showing( package contents)?|editable URL|(File|FTP|News|Media|Web) [Ss]ervers|Telnet hosts|Directory services|Remote applications|waiting until completion|saving( (in|to))?|path (for|to( (((current|frontmost) )?application|resource))?)|POSIX (file|path)|(background|RGB) color|(OK|cancel) button name|cancel button|button(s)?|cubic ((centi)?met(re|er)s|yards|feet|inches)|square ((kilo)?met(re|er)s|miles|yards|feet)|(centi|kilo)?met(re|er)s|miles|yards|feet|inches|lit(re|er)s|gallons|quarts|(kilo)?grams|ounces|pounds|degrees (Celsius|Fahrenheit|Kelvin)|print( (dialog|settings))?|clos(e(able)?|ing)|(de)?miniaturized|miniaturizable|zoom(ed|able)|attribute run|action (method|property|title)|phone|email|((start|end)ing|home) page|((birth|creation|current|custom|modification) )?date|((((phonetic )?(first|last|middle))|computer|host|maiden|related) |nick)?name|aim|icq|jabber|msn|yahoo|address(es)?|save addressbook|should enable action|city|country( code)?|formatte(r|d address)|(palette )?label|state|street|zip|AIM [Hh]andle(s)?|my card|select(ion| all)?|unsaved|(alpha )?value|entr(y|ies)|group|(ICQ|Jabber|MSN) handle|person|people|company|department|icon image|job title|note|organization|suffix|vcard|url|copies|collating|pages (across|down)|request print time|target( printer)?|((GUI Scripting|Script menu) )?enabled|show Computer scripts|(de)?activated|awake from nib|became (key|main)|call method|of (class|object)|center|clicked toolbar item|closed|for document|exposed|(can )?hide|idle|keyboard (down|up)|event( (number|type))?|launch(ed)?|load (image|movie|nib|sound)|owner|log|mouse (down|dragged|entered|exited|moved|up)|move|column|localization|resource|script|register|drag (info|types)|resigned (active|key|main)|resiz(e(d)?|able)|right mouse (down|dragged|up)|scroll wheel|(at )?index|should (close|open( untitled)?|quit( after last window closed)?|zoom)|((proposed|screen) )?bounds|show(n)?|behind|in front of|size (mode|to fit)|update(d| toolbar item)?|was (hidden|miniaturized)|will (become active|close|finish launching|hide|miniaturize|move|open|quit|(resign )?active|((maximum|minimum|proposed) )?size|show|zoom)|bundle|data source|movie|pasteboard|sound|tool(bar| tip)|(color|open|save) panel|coordinate system|frontmost|main( (bundle|menu|window))?|((services|(excluded from )?windows) )?menu|((executable|frameworks|resource|scripts|shared (frameworks|support)) )?path|(selected item )?identifier|data|content(s| view)?|character(s)?|click count|(command|control|option|shift) key down|context|delta (x|y|z)|key( code)?|location|pressure|unmodified characters|types|(first )?responder|playing|(allowed|selectable) identifiers|allows customization|(auto saves )?configuration|visible|image( name)?|menu form representation|tag|user(-| )defaults|associated file name|(auto|needs) display|current field editor|floating|has (resize indicator|shadow)|hides when deactivated|level|minimized (image|title)|opaque|position|release when closed|sheet|title(d)?)\b/g, + css: 'color3' }, + + { regex: new RegExp(this.getKeywords(specials), 'gm'), css: 'color3' }, + { regex: new RegExp(this.getKeywords(keywords), 'gm'), css: 'keyword' }, + { regex: new RegExp(this.getKeywords(ordinals), 'gm'), css: 'keyword' } + ]; + }; + + Brush.prototype = new SyntaxHighlighter.Highlighter(); + Brush.aliases = ['applescript']; + + SyntaxHighlighter.brushes.AppleScript = Brush; + + // CommonJS + typeof(exports) != 'undefined' ? exports.Brush = Brush : null; +})(); diff --git a/scm-webapp/src/main/webapp/resources/syntaxhighlighter/scripts/shBrushBash.js b/scm-webapp/src/main/webapp/resources/syntaxhighlighter/scripts/shBrushBash.js new file mode 100644 index 0000000000..8c296969ff --- /dev/null +++ b/scm-webapp/src/main/webapp/resources/syntaxhighlighter/scripts/shBrushBash.js @@ -0,0 +1,59 @@ +/** + * SyntaxHighlighter + * http://alexgorbatchev.com/SyntaxHighlighter + * + * SyntaxHighlighter is donationware. If you are using it, please donate. + * http://alexgorbatchev.com/SyntaxHighlighter/donate.html + * + * @version + * 3.0.83 (July 02 2010) + * + * @copyright + * Copyright (C) 2004-2010 Alex Gorbatchev. + * + * @license + * Dual licensed under the MIT and GPL licenses. + */ +;(function() +{ + // CommonJS + typeof(require) != 'undefined' ? SyntaxHighlighter = require('shCore').SyntaxHighlighter : null; + + function Brush() + { + var keywords = 'if fi then elif else for do done until while break continue case function return in eq ne ge le'; + var commands = 'alias apropos awk basename bash bc bg builtin bzip2 cal cat cd cfdisk chgrp chmod chown chroot' + + 'cksum clear cmp comm command cp cron crontab csplit cut date dc dd ddrescue declare df ' + + 'diff diff3 dig dir dircolors dirname dirs du echo egrep eject enable env ethtool eval ' + + 'exec exit expand export expr false fdformat fdisk fg fgrep file find fmt fold format ' + + 'free fsck ftp gawk getopts grep groups gzip hash head history hostname id ifconfig ' + + 'import install join kill less let ln local locate logname logout look lpc lpr lprint ' + + 'lprintd lprintq lprm ls lsof make man mkdir mkfifo mkisofs mknod more mount mtools ' + + 'mv netstat nice nl nohup nslookup open op passwd paste pathchk ping popd pr printcap ' + + 'printenv printf ps pushd pwd quota quotacheck quotactl ram rcp read readonly renice ' + + 'remsync rm rmdir rsync screen scp sdiff sed select seq set sftp shift shopt shutdown ' + + 'sleep sort source split ssh strace su sudo sum symlink sync tail tar tee test time ' + + 'times touch top traceroute trap tr true tsort tty type ulimit umask umount unalias ' + + 'uname unexpand uniq units unset unshar useradd usermod users uuencode uudecode v vdir ' + + 'vi watch wc whereis which who whoami Wget xargs yes' + ; + + this.regexList = [ + { regex: /^#!.*$/gm, css: 'preprocessor bold' }, + { regex: /\/[\w-\/]+/gm, css: 'plain' }, + { regex: SyntaxHighlighter.regexLib.singleLinePerlComments, css: 'comments' }, // one line comments + { regex: SyntaxHighlighter.regexLib.doubleQuotedString, css: 'string' }, // double quoted strings + { regex: SyntaxHighlighter.regexLib.singleQuotedString, css: 'string' }, // single quoted strings + { regex: new RegExp(this.getKeywords(keywords), 'gm'), css: 'keyword' }, // keywords + { regex: new RegExp(this.getKeywords(commands), 'gm'), css: 'functions' } // commands + ]; + } + + Brush.prototype = new SyntaxHighlighter.Highlighter(); + Brush.aliases = ['bash', 'shell']; + + SyntaxHighlighter.brushes.Bash = Brush; + + // CommonJS + typeof(exports) != 'undefined' ? exports.Brush = Brush : null; +})(); diff --git a/scm-webapp/src/main/webapp/resources/syntaxhighlighter/scripts/shBrushCSharp.js b/scm-webapp/src/main/webapp/resources/syntaxhighlighter/scripts/shBrushCSharp.js new file mode 100644 index 0000000000..079214efe1 --- /dev/null +++ b/scm-webapp/src/main/webapp/resources/syntaxhighlighter/scripts/shBrushCSharp.js @@ -0,0 +1,65 @@ +/** + * SyntaxHighlighter + * http://alexgorbatchev.com/SyntaxHighlighter + * + * SyntaxHighlighter is donationware. If you are using it, please donate. + * http://alexgorbatchev.com/SyntaxHighlighter/donate.html + * + * @version + * 3.0.83 (July 02 2010) + * + * @copyright + * Copyright (C) 2004-2010 Alex Gorbatchev. + * + * @license + * Dual licensed under the MIT and GPL licenses. + */ +;(function() +{ + // CommonJS + typeof(require) != 'undefined' ? SyntaxHighlighter = require('shCore').SyntaxHighlighter : null; + + function Brush() + { + var keywords = 'abstract as base bool break byte case catch char checked class const ' + + 'continue decimal default delegate do double else enum event explicit ' + + 'extern false finally fixed float for foreach get goto if implicit in int ' + + 'interface internal is lock long namespace new null object operator out ' + + 'override params private protected public readonly ref return sbyte sealed set ' + + 'short sizeof stackalloc static string struct switch this throw true try ' + + 'typeof uint ulong unchecked unsafe ushort using virtual void while'; + + function fixComments(match, regexInfo) + { + var css = (match[0].indexOf("///") == 0) + ? 'color1' + : 'comments' + ; + + return [new SyntaxHighlighter.Match(match[0], match.index, css)]; + } + + this.regexList = [ + { regex: SyntaxHighlighter.regexLib.singleLineCComments, func : fixComments }, // one line comments + { regex: SyntaxHighlighter.regexLib.multiLineCComments, css: 'comments' }, // multiline comments + { regex: /@"(?:[^"]|"")*"/g, css: 'string' }, // @-quoted strings + { regex: SyntaxHighlighter.regexLib.doubleQuotedString, css: 'string' }, // strings + { regex: SyntaxHighlighter.regexLib.singleQuotedString, css: 'string' }, // strings + { regex: /^\s*#.*/gm, css: 'preprocessor' }, // preprocessor tags like #region and #endregion + { regex: new RegExp(this.getKeywords(keywords), 'gm'), css: 'keyword' }, // c# keyword + { regex: /\bpartial(?=\s+(?:class|interface|struct)\b)/g, css: 'keyword' }, // contextual keyword: 'partial' + { regex: /\byield(?=\s+(?:return|break)\b)/g, css: 'keyword' } // contextual keyword: 'yield' + ]; + + this.forHtmlScript(SyntaxHighlighter.regexLib.aspScriptTags); + }; + + Brush.prototype = new SyntaxHighlighter.Highlighter(); + Brush.aliases = ['c#', 'c-sharp', 'csharp']; + + SyntaxHighlighter.brushes.CSharp = Brush; + + // CommonJS + typeof(exports) != 'undefined' ? exports.Brush = Brush : null; +})(); + diff --git a/scm-webapp/src/main/webapp/resources/syntaxhighlighter/scripts/shBrushColdFusion.js b/scm-webapp/src/main/webapp/resources/syntaxhighlighter/scripts/shBrushColdFusion.js new file mode 100644 index 0000000000..627dbb9b76 --- /dev/null +++ b/scm-webapp/src/main/webapp/resources/syntaxhighlighter/scripts/shBrushColdFusion.js @@ -0,0 +1,100 @@ +/** + * SyntaxHighlighter + * http://alexgorbatchev.com/SyntaxHighlighter + * + * SyntaxHighlighter is donationware. If you are using it, please donate. + * http://alexgorbatchev.com/SyntaxHighlighter/donate.html + * + * @version + * 3.0.83 (July 02 2010) + * + * @copyright + * Copyright (C) 2004-2010 Alex Gorbatchev. + * + * @license + * Dual licensed under the MIT and GPL licenses. + */ +;(function() +{ + // CommonJS + typeof(require) != 'undefined' ? SyntaxHighlighter = require('shCore').SyntaxHighlighter : null; + + function Brush() + { + // Contributed by Jen + // http://www.jensbits.com/2009/05/14/coldfusion-brush-for-syntaxhighlighter-plus + + var funcs = 'Abs ACos AddSOAPRequestHeader AddSOAPResponseHeader AjaxLink AjaxOnLoad ArrayAppend ArrayAvg ArrayClear ArrayDeleteAt ' + + 'ArrayInsertAt ArrayIsDefined ArrayIsEmpty ArrayLen ArrayMax ArrayMin ArraySet ArraySort ArraySum ArraySwap ArrayToList ' + + 'Asc ASin Atn BinaryDecode BinaryEncode BitAnd BitMaskClear BitMaskRead BitMaskSet BitNot BitOr BitSHLN BitSHRN BitXor ' + + 'Ceiling CharsetDecode CharsetEncode Chr CJustify Compare CompareNoCase Cos CreateDate CreateDateTime CreateObject ' + + 'CreateODBCDate CreateODBCDateTime CreateODBCTime CreateTime CreateTimeSpan CreateUUID DateAdd DateCompare DateConvert ' + + 'DateDiff DateFormat DatePart Day DayOfWeek DayOfWeekAsString DayOfYear DaysInMonth DaysInYear DE DecimalFormat DecrementValue ' + + 'Decrypt DecryptBinary DeleteClientVariable DeserializeJSON DirectoryExists DollarFormat DotNetToCFType Duplicate Encrypt ' + + 'EncryptBinary Evaluate Exp ExpandPath FileClose FileCopy FileDelete FileExists FileIsEOF FileMove FileOpen FileRead ' + + 'FileReadBinary FileReadLine FileSetAccessMode FileSetAttribute FileSetLastModified FileWrite Find FindNoCase FindOneOf ' + + 'FirstDayOfMonth Fix FormatBaseN GenerateSecretKey GetAuthUser GetBaseTagData GetBaseTagList GetBaseTemplatePath ' + + 'GetClientVariablesList GetComponentMetaData GetContextRoot GetCurrentTemplatePath GetDirectoryFromPath GetEncoding ' + + 'GetException GetFileFromPath GetFileInfo GetFunctionList GetGatewayHelper GetHttpRequestData GetHttpTimeString ' + + 'GetK2ServerDocCount GetK2ServerDocCountLimit GetLocale GetLocaleDisplayName GetLocalHostIP GetMetaData GetMetricData ' + + 'GetPageContext GetPrinterInfo GetProfileSections GetProfileString GetReadableImageFormats GetSOAPRequest GetSOAPRequestHeader ' + + 'GetSOAPResponse GetSOAPResponseHeader GetTempDirectory GetTempFile GetTemplatePath GetTickCount GetTimeZoneInfo GetToken ' + + 'GetUserRoles GetWriteableImageFormats Hash Hour HTMLCodeFormat HTMLEditFormat IIf ImageAddBorder ImageBlur ImageClearRect ' + + 'ImageCopy ImageCrop ImageDrawArc ImageDrawBeveledRect ImageDrawCubicCurve ImageDrawLine ImageDrawLines ImageDrawOval ' + + 'ImageDrawPoint ImageDrawQuadraticCurve ImageDrawRect ImageDrawRoundRect ImageDrawText ImageFlip ImageGetBlob ImageGetBufferedImage ' + + 'ImageGetEXIFTag ImageGetHeight ImageGetIPTCTag ImageGetWidth ImageGrayscale ImageInfo ImageNegative ImageNew ImageOverlay ImagePaste ' + + 'ImageRead ImageReadBase64 ImageResize ImageRotate ImageRotateDrawingAxis ImageScaleToFit ImageSetAntialiasing ImageSetBackgroundColor ' + + 'ImageSetDrawingColor ImageSetDrawingStroke ImageSetDrawingTransparency ImageSharpen ImageShear ImageShearDrawingAxis ImageTranslate ' + + 'ImageTranslateDrawingAxis ImageWrite ImageWriteBase64 ImageXORDrawingMode IncrementValue InputBaseN Insert Int IsArray IsBinary ' + + 'IsBoolean IsCustomFunction IsDate IsDDX IsDebugMode IsDefined IsImage IsImageFile IsInstanceOf IsJSON IsLeapYear IsLocalHost ' + + 'IsNumeric IsNumericDate IsObject IsPDFFile IsPDFObject IsQuery IsSimpleValue IsSOAPRequest IsStruct IsUserInAnyRole IsUserInRole ' + + 'IsUserLoggedIn IsValid IsWDDX IsXML IsXmlAttribute IsXmlDoc IsXmlElem IsXmlNode IsXmlRoot JavaCast JSStringFormat LCase Left Len ' + + 'ListAppend ListChangeDelims ListContains ListContainsNoCase ListDeleteAt ListFind ListFindNoCase ListFirst ListGetAt ListInsertAt ' + + 'ListLast ListLen ListPrepend ListQualify ListRest ListSetAt ListSort ListToArray ListValueCount ListValueCountNoCase LJustify Log ' + + 'Log10 LSCurrencyFormat LSDateFormat LSEuroCurrencyFormat LSIsCurrency LSIsDate LSIsNumeric LSNumberFormat LSParseCurrency LSParseDateTime ' + + 'LSParseEuroCurrency LSParseNumber LSTimeFormat LTrim Max Mid Min Minute Month MonthAsString Now NumberFormat ParagraphFormat ParseDateTime ' + + 'Pi PrecisionEvaluate PreserveSingleQuotes Quarter QueryAddColumn QueryAddRow QueryConvertForGrid QueryNew QuerySetCell QuotedValueList Rand ' + + 'Randomize RandRange REFind REFindNoCase ReleaseComObject REMatch REMatchNoCase RemoveChars RepeatString Replace ReplaceList ReplaceNoCase ' + + 'REReplace REReplaceNoCase Reverse Right RJustify Round RTrim Second SendGatewayMessage SerializeJSON SetEncoding SetLocale SetProfileString ' + + 'SetVariable Sgn Sin Sleep SpanExcluding SpanIncluding Sqr StripCR StructAppend StructClear StructCopy StructCount StructDelete StructFind ' + + 'StructFindKey StructFindValue StructGet StructInsert StructIsEmpty StructKeyArray StructKeyExists StructKeyList StructKeyList StructNew ' + + 'StructSort StructUpdate Tan TimeFormat ToBase64 ToBinary ToScript ToString Trim UCase URLDecode URLEncodedFormat URLSessionFormat Val ' + + 'ValueList VerifyClient Week Wrap Wrap WriteOutput XmlChildPos XmlElemNew XmlFormat XmlGetNodeType XmlNew XmlParse XmlSearch XmlTransform ' + + 'XmlValidate Year YesNoFormat'; + + var keywords = 'cfabort cfajaximport cfajaxproxy cfapplet cfapplication cfargument cfassociate cfbreak cfcache cfcalendar ' + + 'cfcase cfcatch cfchart cfchartdata cfchartseries cfcol cfcollection cfcomponent cfcontent cfcookie cfdbinfo ' + + 'cfdefaultcase cfdirectory cfdiv cfdocument cfdocumentitem cfdocumentsection cfdump cfelse cfelseif cferror ' + + 'cfexchangecalendar cfexchangeconnection cfexchangecontact cfexchangefilter cfexchangemail cfexchangetask ' + + 'cfexecute cfexit cffeed cffile cfflush cfform cfformgroup cfformitem cfftp cffunction cfgrid cfgridcolumn ' + + 'cfgridrow cfgridupdate cfheader cfhtmlhead cfhttp cfhttpparam cfif cfimage cfimport cfinclude cfindex ' + + 'cfinput cfinsert cfinterface cfinvoke cfinvokeargument cflayout cflayoutarea cfldap cflocation cflock cflog ' + + 'cflogin cfloginuser cflogout cfloop cfmail cfmailparam cfmailpart cfmenu cfmenuitem cfmodule cfNTauthenticate ' + + 'cfobject cfobjectcache cfoutput cfparam cfpdf cfpdfform cfpdfformparam cfpdfparam cfpdfsubform cfpod cfpop ' + + 'cfpresentation cfpresentationslide cfpresenter cfprint cfprocessingdirective cfprocparam cfprocresult ' + + 'cfproperty cfquery cfqueryparam cfregistry cfreport cfreportparam cfrethrow cfreturn cfsavecontent cfschedule ' + + 'cfscript cfsearch cfselect cfset cfsetting cfsilent cfslider cfsprydataset cfstoredproc cfswitch cftable ' + + 'cftextarea cfthread cfthrow cftimer cftooltip cftrace cftransaction cftree cftreeitem cftry cfupdate cfwddx ' + + 'cfwindow cfxml cfzip cfzipparam'; + + var operators = 'all and any between cross in join like not null or outer some'; + + this.regexList = [ + { regex: new RegExp('--(.*)$', 'gm'), css: 'comments' }, // one line and multiline comments + { regex: SyntaxHighlighter.regexLib.xmlComments, css: 'comments' }, // single quoted strings + { regex: SyntaxHighlighter.regexLib.doubleQuotedString, css: 'string' }, // double quoted strings + { regex: SyntaxHighlighter.regexLib.singleQuotedString, css: 'string' }, // single quoted strings + { regex: new RegExp(this.getKeywords(funcs), 'gmi'), css: 'functions' }, // functions + { regex: new RegExp(this.getKeywords(operators), 'gmi'), css: 'color1' }, // operators and such + { regex: new RegExp(this.getKeywords(keywords), 'gmi'), css: 'keyword' } // keyword + ]; + } + + Brush.prototype = new SyntaxHighlighter.Highlighter(); + Brush.aliases = ['coldfusion','cf']; + + SyntaxHighlighter.brushes.ColdFusion = Brush; + + // CommonJS + typeof(exports) != 'undefined' ? exports.Brush = Brush : null; +})(); diff --git a/scm-webapp/src/main/webapp/resources/syntaxhighlighter/scripts/shBrushCpp.js b/scm-webapp/src/main/webapp/resources/syntaxhighlighter/scripts/shBrushCpp.js new file mode 100644 index 0000000000..9f70d3aed6 --- /dev/null +++ b/scm-webapp/src/main/webapp/resources/syntaxhighlighter/scripts/shBrushCpp.js @@ -0,0 +1,97 @@ +/** + * SyntaxHighlighter + * http://alexgorbatchev.com/SyntaxHighlighter + * + * SyntaxHighlighter is donationware. If you are using it, please donate. + * http://alexgorbatchev.com/SyntaxHighlighter/donate.html + * + * @version + * 3.0.83 (July 02 2010) + * + * @copyright + * Copyright (C) 2004-2010 Alex Gorbatchev. + * + * @license + * Dual licensed under the MIT and GPL licenses. + */ +;(function() +{ + // CommonJS + typeof(require) != 'undefined' ? SyntaxHighlighter = require('shCore').SyntaxHighlighter : null; + + function Brush() + { + // Copyright 2006 Shin, YoungJin + + var datatypes = 'ATOM BOOL BOOLEAN BYTE CHAR COLORREF DWORD DWORDLONG DWORD_PTR ' + + 'DWORD32 DWORD64 FLOAT HACCEL HALF_PTR HANDLE HBITMAP HBRUSH ' + + 'HCOLORSPACE HCONV HCONVLIST HCURSOR HDC HDDEDATA HDESK HDROP HDWP ' + + 'HENHMETAFILE HFILE HFONT HGDIOBJ HGLOBAL HHOOK HICON HINSTANCE HKEY ' + + 'HKL HLOCAL HMENU HMETAFILE HMODULE HMONITOR HPALETTE HPEN HRESULT ' + + 'HRGN HRSRC HSZ HWINSTA HWND INT INT_PTR INT32 INT64 LANGID LCID LCTYPE ' + + 'LGRPID LONG LONGLONG LONG_PTR LONG32 LONG64 LPARAM LPBOOL LPBYTE LPCOLORREF ' + + 'LPCSTR LPCTSTR LPCVOID LPCWSTR LPDWORD LPHANDLE LPINT LPLONG LPSTR LPTSTR ' + + 'LPVOID LPWORD LPWSTR LRESULT PBOOL PBOOLEAN PBYTE PCHAR PCSTR PCTSTR PCWSTR ' + + 'PDWORDLONG PDWORD_PTR PDWORD32 PDWORD64 PFLOAT PHALF_PTR PHANDLE PHKEY PINT ' + + 'PINT_PTR PINT32 PINT64 PLCID PLONG PLONGLONG PLONG_PTR PLONG32 PLONG64 POINTER_32 ' + + 'POINTER_64 PSHORT PSIZE_T PSSIZE_T PSTR PTBYTE PTCHAR PTSTR PUCHAR PUHALF_PTR ' + + 'PUINT PUINT_PTR PUINT32 PUINT64 PULONG PULONGLONG PULONG_PTR PULONG32 PULONG64 ' + + 'PUSHORT PVOID PWCHAR PWORD PWSTR SC_HANDLE SC_LOCK SERVICE_STATUS_HANDLE SHORT ' + + 'SIZE_T SSIZE_T TBYTE TCHAR UCHAR UHALF_PTR UINT UINT_PTR UINT32 UINT64 ULONG ' + + 'ULONGLONG ULONG_PTR ULONG32 ULONG64 USHORT USN VOID WCHAR WORD WPARAM WPARAM WPARAM ' + + 'char bool short int __int32 __int64 __int8 __int16 long float double __wchar_t ' + + 'clock_t _complex _dev_t _diskfree_t div_t ldiv_t _exception _EXCEPTION_POINTERS ' + + 'FILE _finddata_t _finddatai64_t _wfinddata_t _wfinddatai64_t __finddata64_t ' + + '__wfinddata64_t _FPIEEE_RECORD fpos_t _HEAPINFO _HFILE lconv intptr_t ' + + 'jmp_buf mbstate_t _off_t _onexit_t _PNH ptrdiff_t _purecall_handler ' + + 'sig_atomic_t size_t _stat __stat64 _stati64 terminate_function ' + + 'time_t __time64_t _timeb __timeb64 tm uintptr_t _utimbuf ' + + 'va_list wchar_t wctrans_t wctype_t wint_t signed'; + + var keywords = 'break case catch class const __finally __exception __try ' + + 'const_cast continue private public protected __declspec ' + + 'default delete deprecated dllexport dllimport do dynamic_cast ' + + 'else enum explicit extern if for friend goto inline ' + + 'mutable naked namespace new noinline noreturn nothrow ' + + 'register reinterpret_cast return selectany ' + + 'sizeof static static_cast struct switch template this ' + + 'thread throw true false try typedef typeid typename union ' + + 'using uuid virtual void volatile whcar_t while'; + + var functions = 'assert isalnum isalpha iscntrl isdigit isgraph islower isprint' + + 'ispunct isspace isupper isxdigit tolower toupper errno localeconv ' + + 'setlocale acos asin atan atan2 ceil cos cosh exp fabs floor fmod ' + + 'frexp ldexp log log10 modf pow sin sinh sqrt tan tanh jmp_buf ' + + 'longjmp setjmp raise signal sig_atomic_t va_arg va_end va_start ' + + 'clearerr fclose feof ferror fflush fgetc fgetpos fgets fopen ' + + 'fprintf fputc fputs fread freopen fscanf fseek fsetpos ftell ' + + 'fwrite getc getchar gets perror printf putc putchar puts remove ' + + 'rename rewind scanf setbuf setvbuf sprintf sscanf tmpfile tmpnam ' + + 'ungetc vfprintf vprintf vsprintf abort abs atexit atof atoi atol ' + + 'bsearch calloc div exit free getenv labs ldiv malloc mblen mbstowcs ' + + 'mbtowc qsort rand realloc srand strtod strtol strtoul system ' + + 'wcstombs wctomb memchr memcmp memcpy memmove memset strcat strchr ' + + 'strcmp strcoll strcpy strcspn strerror strlen strncat strncmp ' + + 'strncpy strpbrk strrchr strspn strstr strtok strxfrm asctime ' + + 'clock ctime difftime gmtime localtime mktime strftime time'; + + this.regexList = [ + { regex: SyntaxHighlighter.regexLib.singleLineCComments, css: 'comments' }, // one line comments + { regex: SyntaxHighlighter.regexLib.multiLineCComments, css: 'comments' }, // multiline comments + { regex: SyntaxHighlighter.regexLib.doubleQuotedString, css: 'string' }, // strings + { regex: SyntaxHighlighter.regexLib.singleQuotedString, css: 'string' }, // strings + { regex: /^ *#.*/gm, css: 'preprocessor' }, + { regex: new RegExp(this.getKeywords(datatypes), 'gm'), css: 'color1 bold' }, + { regex: new RegExp(this.getKeywords(functions), 'gm'), css: 'functions bold' }, + { regex: new RegExp(this.getKeywords(keywords), 'gm'), css: 'keyword bold' } + ]; + }; + + Brush.prototype = new SyntaxHighlighter.Highlighter(); + Brush.aliases = ['cpp', 'c']; + + SyntaxHighlighter.brushes.Cpp = Brush; + + // CommonJS + typeof(exports) != 'undefined' ? exports.Brush = Brush : null; +})(); diff --git a/scm-webapp/src/main/webapp/resources/syntaxhighlighter/scripts/shBrushCss.js b/scm-webapp/src/main/webapp/resources/syntaxhighlighter/scripts/shBrushCss.js new file mode 100644 index 0000000000..4297a9a648 --- /dev/null +++ b/scm-webapp/src/main/webapp/resources/syntaxhighlighter/scripts/shBrushCss.js @@ -0,0 +1,91 @@ +/** + * SyntaxHighlighter + * http://alexgorbatchev.com/SyntaxHighlighter + * + * SyntaxHighlighter is donationware. If you are using it, please donate. + * http://alexgorbatchev.com/SyntaxHighlighter/donate.html + * + * @version + * 3.0.83 (July 02 2010) + * + * @copyright + * Copyright (C) 2004-2010 Alex Gorbatchev. + * + * @license + * Dual licensed under the MIT and GPL licenses. + */ +;(function() +{ + // CommonJS + typeof(require) != 'undefined' ? SyntaxHighlighter = require('shCore').SyntaxHighlighter : null; + + function Brush() + { + function getKeywordsCSS(str) + { + return '\\b([a-z_]|)' + str.replace(/ /g, '(?=:)\\b|\\b([a-z_\\*]|\\*|)') + '(?=:)\\b'; + }; + + function getValuesCSS(str) + { + return '\\b' + str.replace(/ /g, '(?!-)(?!:)\\b|\\b()') + '\:\\b'; + }; + + var keywords = 'ascent azimuth background-attachment background-color background-image background-position ' + + 'background-repeat background baseline bbox border-collapse border-color border-spacing border-style border-top ' + + 'border-right border-bottom border-left border-top-color border-right-color border-bottom-color border-left-color ' + + 'border-top-style border-right-style border-bottom-style border-left-style border-top-width border-right-width ' + + 'border-bottom-width border-left-width border-width border bottom cap-height caption-side centerline clear clip color ' + + 'content counter-increment counter-reset cue-after cue-before cue cursor definition-src descent direction display ' + + 'elevation empty-cells float font-size-adjust font-family font-size font-stretch font-style font-variant font-weight font ' + + 'height left letter-spacing line-height list-style-image list-style-position list-style-type list-style margin-top ' + + 'margin-right margin-bottom margin-left margin marker-offset marks mathline max-height max-width min-height min-width orphans ' + + 'outline-color outline-style outline-width outline overflow padding-top padding-right padding-bottom padding-left padding page ' + + 'page-break-after page-break-before page-break-inside pause pause-after pause-before pitch pitch-range play-during position ' + + 'quotes right richness size slope src speak-header speak-numeral speak-punctuation speak speech-rate stemh stemv stress ' + + 'table-layout text-align top text-decoration text-indent text-shadow text-transform unicode-bidi unicode-range units-per-em ' + + 'vertical-align visibility voice-family volume white-space widows width widths word-spacing x-height z-index'; + + var values = 'above absolute all always aqua armenian attr aural auto avoid baseline behind below bidi-override black blink block blue bold bolder '+ + 'both bottom braille capitalize caption center center-left center-right circle close-quote code collapse compact condensed '+ + 'continuous counter counters crop cross crosshair cursive dashed decimal decimal-leading-zero default digits disc dotted double '+ + 'embed embossed e-resize expanded extra-condensed extra-expanded fantasy far-left far-right fast faster fixed format fuchsia '+ + 'gray green groove handheld hebrew help hidden hide high higher icon inline-table inline inset inside invert italic '+ + 'justify landscape large larger left-side left leftwards level lighter lime line-through list-item local loud lower-alpha '+ + 'lowercase lower-greek lower-latin lower-roman lower low ltr marker maroon medium message-box middle mix move narrower '+ + 'navy ne-resize no-close-quote none no-open-quote no-repeat normal nowrap n-resize nw-resize oblique olive once open-quote outset '+ + 'outside overline pointer portrait pre print projection purple red relative repeat repeat-x repeat-y rgb ridge right right-side '+ + 'rightwards rtl run-in screen scroll semi-condensed semi-expanded separate se-resize show silent silver slower slow '+ + 'small small-caps small-caption smaller soft solid speech spell-out square s-resize static status-bar sub super sw-resize '+ + 'table-caption table-cell table-column table-column-group table-footer-group table-header-group table-row table-row-group teal '+ + 'text-bottom text-top thick thin top transparent tty tv ultra-condensed ultra-expanded underline upper-alpha uppercase upper-latin '+ + 'upper-roman url visible wait white wider w-resize x-fast x-high x-large x-loud x-low x-slow x-small x-soft xx-large xx-small yellow'; + + var fonts = '[mM]onospace [tT]ahoma [vV]erdana [aA]rial [hH]elvetica [sS]ans-serif [sS]erif [cC]ourier mono sans serif'; + + this.regexList = [ + { regex: SyntaxHighlighter.regexLib.multiLineCComments, css: 'comments' }, // multiline comments + { regex: SyntaxHighlighter.regexLib.doubleQuotedString, css: 'string' }, // double quoted strings + { regex: SyntaxHighlighter.regexLib.singleQuotedString, css: 'string' }, // single quoted strings + { regex: /\#[a-fA-F0-9]{3,6}/g, css: 'value' }, // html colors + { regex: /(-?\d+)(\.\d+)?(px|em|pt|\:|\%|)/g, css: 'value' }, // sizes + { regex: /!important/g, css: 'color3' }, // !important + { regex: new RegExp(getKeywordsCSS(keywords), 'gm'), css: 'keyword' }, // keywords + { regex: new RegExp(getValuesCSS(values), 'g'), css: 'value' }, // values + { regex: new RegExp(this.getKeywords(fonts), 'g'), css: 'color1' } // fonts + ]; + + this.forHtmlScript({ + left: /(<|<)\s*style.*?(>|>)/gi, + right: /(<|<)\/\s*style\s*(>|>)/gi + }); + }; + + Brush.prototype = new SyntaxHighlighter.Highlighter(); + Brush.aliases = ['css']; + + SyntaxHighlighter.brushes.CSS = Brush; + + // CommonJS + typeof(exports) != 'undefined' ? exports.Brush = Brush : null; +})(); diff --git a/scm-webapp/src/main/webapp/resources/syntaxhighlighter/scripts/shBrushDelphi.js b/scm-webapp/src/main/webapp/resources/syntaxhighlighter/scripts/shBrushDelphi.js new file mode 100644 index 0000000000..e1060d4468 --- /dev/null +++ b/scm-webapp/src/main/webapp/resources/syntaxhighlighter/scripts/shBrushDelphi.js @@ -0,0 +1,55 @@ +/** + * SyntaxHighlighter + * http://alexgorbatchev.com/SyntaxHighlighter + * + * SyntaxHighlighter is donationware. If you are using it, please donate. + * http://alexgorbatchev.com/SyntaxHighlighter/donate.html + * + * @version + * 3.0.83 (July 02 2010) + * + * @copyright + * Copyright (C) 2004-2010 Alex Gorbatchev. + * + * @license + * Dual licensed under the MIT and GPL licenses. + */ +;(function() +{ + // CommonJS + typeof(require) != 'undefined' ? SyntaxHighlighter = require('shCore').SyntaxHighlighter : null; + + function Brush() + { + var keywords = 'abs addr and ansichar ansistring array as asm begin boolean byte cardinal ' + + 'case char class comp const constructor currency destructor div do double ' + + 'downto else end except exports extended false file finalization finally ' + + 'for function goto if implementation in inherited int64 initialization ' + + 'integer interface is label library longint longword mod nil not object ' + + 'of on or packed pansichar pansistring pchar pcurrency pdatetime pextended ' + + 'pint64 pointer private procedure program property pshortstring pstring ' + + 'pvariant pwidechar pwidestring protected public published raise real real48 ' + + 'record repeat set shl shortint shortstring shr single smallint string then ' + + 'threadvar to true try type unit until uses val var varirnt while widechar ' + + 'widestring with word write writeln xor'; + + this.regexList = [ + { regex: /\(\*[\s\S]*?\*\)/gm, css: 'comments' }, // multiline comments (* *) + { regex: /{(?!\$)[\s\S]*?}/gm, css: 'comments' }, // multiline comments { } + { regex: SyntaxHighlighter.regexLib.singleLineCComments, css: 'comments' }, // one line + { regex: SyntaxHighlighter.regexLib.singleQuotedString, css: 'string' }, // strings + { regex: /\{\$[a-zA-Z]+ .+\}/g, css: 'color1' }, // compiler Directives and Region tags + { regex: /\b[\d\.]+\b/g, css: 'value' }, // numbers 12345 + { regex: /\$[a-zA-Z0-9]+\b/g, css: 'value' }, // numbers $F5D3 + { regex: new RegExp(this.getKeywords(keywords), 'gmi'), css: 'keyword' } // keyword + ]; + }; + + Brush.prototype = new SyntaxHighlighter.Highlighter(); + Brush.aliases = ['delphi', 'pascal', 'pas']; + + SyntaxHighlighter.brushes.Delphi = Brush; + + // CommonJS + typeof(exports) != 'undefined' ? exports.Brush = Brush : null; +})(); diff --git a/scm-webapp/src/main/webapp/resources/syntaxhighlighter/scripts/shBrushDiff.js b/scm-webapp/src/main/webapp/resources/syntaxhighlighter/scripts/shBrushDiff.js new file mode 100644 index 0000000000..e9b14fc580 --- /dev/null +++ b/scm-webapp/src/main/webapp/resources/syntaxhighlighter/scripts/shBrushDiff.js @@ -0,0 +1,41 @@ +/** + * SyntaxHighlighter + * http://alexgorbatchev.com/SyntaxHighlighter + * + * SyntaxHighlighter is donationware. If you are using it, please donate. + * http://alexgorbatchev.com/SyntaxHighlighter/donate.html + * + * @version + * 3.0.83 (July 02 2010) + * + * @copyright + * Copyright (C) 2004-2010 Alex Gorbatchev. + * + * @license + * Dual licensed under the MIT and GPL licenses. + */ +;(function() +{ + // CommonJS + typeof(require) != 'undefined' ? SyntaxHighlighter = require('shCore').SyntaxHighlighter : null; + + function Brush() + { + this.regexList = [ + { regex: /^\+\+\+.*$/gm, css: 'color2' }, + { regex: /^\-\-\-.*$/gm, css: 'color2' }, + { regex: /^\s.*$/gm, css: 'color1' }, + { regex: /^@@.*@@$/gm, css: 'variable' }, + { regex: /^\+[^\+]{1}.*$/gm, css: 'string' }, + { regex: /^\-[^\-]{1}.*$/gm, css: 'comments' } + ]; + }; + + Brush.prototype = new SyntaxHighlighter.Highlighter(); + Brush.aliases = ['diff', 'patch']; + + SyntaxHighlighter.brushes.Diff = Brush; + + // CommonJS + typeof(exports) != 'undefined' ? exports.Brush = Brush : null; +})(); diff --git a/scm-webapp/src/main/webapp/resources/syntaxhighlighter/scripts/shBrushErlang.js b/scm-webapp/src/main/webapp/resources/syntaxhighlighter/scripts/shBrushErlang.js new file mode 100644 index 0000000000..6ba7d9da87 --- /dev/null +++ b/scm-webapp/src/main/webapp/resources/syntaxhighlighter/scripts/shBrushErlang.js @@ -0,0 +1,52 @@ +/** + * SyntaxHighlighter + * http://alexgorbatchev.com/SyntaxHighlighter + * + * SyntaxHighlighter is donationware. If you are using it, please donate. + * http://alexgorbatchev.com/SyntaxHighlighter/donate.html + * + * @version + * 3.0.83 (July 02 2010) + * + * @copyright + * Copyright (C) 2004-2010 Alex Gorbatchev. + * + * @license + * Dual licensed under the MIT and GPL licenses. + */ +;(function() +{ + // CommonJS + typeof(require) != 'undefined' ? SyntaxHighlighter = require('shCore').SyntaxHighlighter : null; + + function Brush() + { + // Contributed by Jean-Lou Dupont + // http://jldupont.blogspot.com/2009/06/erlang-syntax-highlighter.html + + // According to: http://erlang.org/doc/reference_manual/introduction.html#1.5 + var keywords = 'after and andalso band begin bnot bor bsl bsr bxor '+ + 'case catch cond div end fun if let not of or orelse '+ + 'query receive rem try when xor'+ + // additional + ' module export import define'; + + this.regexList = [ + { regex: new RegExp("[A-Z][A-Za-z0-9_]+", 'g'), css: 'constants' }, + { regex: new RegExp("\\%.+", 'gm'), css: 'comments' }, + { regex: new RegExp("\\?[A-Za-z0-9_]+", 'g'), css: 'preprocessor' }, + { regex: new RegExp("[a-z0-9_]+:[a-z0-9_]+", 'g'), css: 'functions' }, + { regex: SyntaxHighlighter.regexLib.doubleQuotedString, css: 'string' }, + { regex: SyntaxHighlighter.regexLib.singleQuotedString, css: 'string' }, + { regex: new RegExp(this.getKeywords(keywords), 'gm'), css: 'keyword' } + ]; + }; + + Brush.prototype = new SyntaxHighlighter.Highlighter(); + Brush.aliases = ['erl', 'erlang']; + + SyntaxHighlighter.brushes.Erland = Brush; + + // CommonJS + typeof(exports) != 'undefined' ? exports.Brush = Brush : null; +})(); diff --git a/scm-webapp/src/main/webapp/resources/syntaxhighlighter/scripts/shBrushGroovy.js b/scm-webapp/src/main/webapp/resources/syntaxhighlighter/scripts/shBrushGroovy.js new file mode 100644 index 0000000000..6ec5c18521 --- /dev/null +++ b/scm-webapp/src/main/webapp/resources/syntaxhighlighter/scripts/shBrushGroovy.js @@ -0,0 +1,67 @@ +/** + * SyntaxHighlighter + * http://alexgorbatchev.com/SyntaxHighlighter + * + * SyntaxHighlighter is donationware. If you are using it, please donate. + * http://alexgorbatchev.com/SyntaxHighlighter/donate.html + * + * @version + * 3.0.83 (July 02 2010) + * + * @copyright + * Copyright (C) 2004-2010 Alex Gorbatchev. + * + * @license + * Dual licensed under the MIT and GPL licenses. + */ +;(function() +{ + // CommonJS + typeof(require) != 'undefined' ? SyntaxHighlighter = require('shCore').SyntaxHighlighter : null; + + function Brush() + { + // Contributed by Andres Almiray + // http://jroller.com/aalmiray/entry/nice_source_code_syntax_highlighter + + var keywords = 'as assert break case catch class continue def default do else extends finally ' + + 'if in implements import instanceof interface new package property return switch ' + + 'throw throws try while public protected private static'; + var types = 'void boolean byte char short int long float double'; + var constants = 'null'; + var methods = 'allProperties count get size '+ + 'collect each eachProperty eachPropertyName eachWithIndex find findAll ' + + 'findIndexOf grep inject max min reverseEach sort ' + + 'asImmutable asSynchronized flatten intersect join pop reverse subMap toList ' + + 'padRight padLeft contains eachMatch toCharacter toLong toUrl tokenize ' + + 'eachFile eachFileRecurse eachB yte eachLine readBytes readLine getText ' + + 'splitEachLine withReader append encodeBase64 decodeBase64 filterLine ' + + 'transformChar transformLine withOutputStream withPrintWriter withStream ' + + 'withStreams withWriter withWriterAppend write writeLine '+ + 'dump inspect invokeMethod print println step times upto use waitForOrKill '+ + 'getText'; + + this.regexList = [ + { regex: SyntaxHighlighter.regexLib.singleLineCComments, css: 'comments' }, // one line comments + { regex: SyntaxHighlighter.regexLib.multiLineCComments, css: 'comments' }, // multiline comments + { regex: SyntaxHighlighter.regexLib.doubleQuotedString, css: 'string' }, // strings + { regex: SyntaxHighlighter.regexLib.singleQuotedString, css: 'string' }, // strings + { regex: /""".*"""/g, css: 'string' }, // GStrings + { regex: new RegExp('\\b([\\d]+(\\.[\\d]+)?|0x[a-f0-9]+)\\b', 'gi'), css: 'value' }, // numbers + { regex: new RegExp(this.getKeywords(keywords), 'gm'), css: 'keyword' }, // goovy keyword + { regex: new RegExp(this.getKeywords(types), 'gm'), css: 'color1' }, // goovy/java type + { regex: new RegExp(this.getKeywords(constants), 'gm'), css: 'constants' }, // constants + { regex: new RegExp(this.getKeywords(methods), 'gm'), css: 'functions' } // methods + ]; + + this.forHtmlScript(SyntaxHighlighter.regexLib.aspScriptTags); + } + + Brush.prototype = new SyntaxHighlighter.Highlighter(); + Brush.aliases = ['groovy']; + + SyntaxHighlighter.brushes.Groovy = Brush; + + // CommonJS + typeof(exports) != 'undefined' ? exports.Brush = Brush : null; +})(); diff --git a/scm-webapp/src/main/webapp/resources/syntaxhighlighter/scripts/shBrushJScript.js b/scm-webapp/src/main/webapp/resources/syntaxhighlighter/scripts/shBrushJScript.js new file mode 100644 index 0000000000..ff98daba16 --- /dev/null +++ b/scm-webapp/src/main/webapp/resources/syntaxhighlighter/scripts/shBrushJScript.js @@ -0,0 +1,52 @@ +/** + * SyntaxHighlighter + * http://alexgorbatchev.com/SyntaxHighlighter + * + * SyntaxHighlighter is donationware. If you are using it, please donate. + * http://alexgorbatchev.com/SyntaxHighlighter/donate.html + * + * @version + * 3.0.83 (July 02 2010) + * + * @copyright + * Copyright (C) 2004-2010 Alex Gorbatchev. + * + * @license + * Dual licensed under the MIT and GPL licenses. + */ +;(function() +{ + // CommonJS + typeof(require) != 'undefined' ? SyntaxHighlighter = require('shCore').SyntaxHighlighter : null; + + function Brush() + { + var keywords = 'break case catch continue ' + + 'default delete do else false ' + + 'for function if in instanceof ' + + 'new null return super switch ' + + 'this throw true try typeof var while with' + ; + + var r = SyntaxHighlighter.regexLib; + + this.regexList = [ + { regex: r.multiLineDoubleQuotedString, css: 'string' }, // double quoted strings + { regex: r.multiLineSingleQuotedString, css: 'string' }, // single quoted strings + { regex: r.singleLineCComments, css: 'comments' }, // one line comments + { regex: r.multiLineCComments, css: 'comments' }, // multiline comments + { regex: /\s*#.*/gm, css: 'preprocessor' }, // preprocessor tags like #region and #endregion + { regex: new RegExp(this.getKeywords(keywords), 'gm'), css: 'keyword' } // keywords + ]; + + this.forHtmlScript(r.scriptScriptTags); + }; + + Brush.prototype = new SyntaxHighlighter.Highlighter(); + Brush.aliases = ['js', 'jscript', 'javascript']; + + SyntaxHighlighter.brushes.JScript = Brush; + + // CommonJS + typeof(exports) != 'undefined' ? exports.Brush = Brush : null; +})(); diff --git a/scm-webapp/src/main/webapp/resources/syntaxhighlighter/scripts/shBrushJava.js b/scm-webapp/src/main/webapp/resources/syntaxhighlighter/scripts/shBrushJava.js new file mode 100644 index 0000000000..d692fd6382 --- /dev/null +++ b/scm-webapp/src/main/webapp/resources/syntaxhighlighter/scripts/shBrushJava.js @@ -0,0 +1,57 @@ +/** + * SyntaxHighlighter + * http://alexgorbatchev.com/SyntaxHighlighter + * + * SyntaxHighlighter is donationware. If you are using it, please donate. + * http://alexgorbatchev.com/SyntaxHighlighter/donate.html + * + * @version + * 3.0.83 (July 02 2010) + * + * @copyright + * Copyright (C) 2004-2010 Alex Gorbatchev. + * + * @license + * Dual licensed under the MIT and GPL licenses. + */ +;(function() +{ + // CommonJS + typeof(require) != 'undefined' ? SyntaxHighlighter = require('shCore').SyntaxHighlighter : null; + + function Brush() + { + var keywords = 'abstract assert boolean break byte case catch char class const ' + + 'continue default do double else enum extends ' + + 'false final finally float for goto if implements import ' + + 'instanceof int interface long native new null ' + + 'package private protected public return ' + + 'short static strictfp super switch synchronized this throw throws true ' + + 'transient try void volatile while'; + + this.regexList = [ + { regex: SyntaxHighlighter.regexLib.singleLineCComments, css: 'comments' }, // one line comments + { regex: /\/\*([^\*][\s\S]*)?\*\//gm, css: 'comments' }, // multiline comments + { regex: /\/\*(?!\*\/)\*[\s\S]*?\*\//gm, css: 'preprocessor' }, // documentation comments + { regex: SyntaxHighlighter.regexLib.doubleQuotedString, css: 'string' }, // strings + { regex: SyntaxHighlighter.regexLib.singleQuotedString, css: 'string' }, // strings + { regex: /\b([\d]+(\.[\d]+)?|0x[a-f0-9]+)\b/gi, css: 'value' }, // numbers + { regex: /(?!\@interface\b)\@[\$\w]+\b/g, css: 'color1' }, // annotation @anno + { regex: /\@interface\b/g, css: 'color2' }, // @interface keyword + { regex: new RegExp(this.getKeywords(keywords), 'gm'), css: 'keyword' } // java keyword + ]; + + this.forHtmlScript({ + left : /(<|<)%[@!=]?/g, + right : /%(>|>)/g + }); + }; + + Brush.prototype = new SyntaxHighlighter.Highlighter(); + Brush.aliases = ['java']; + + SyntaxHighlighter.brushes.Java = Brush; + + // CommonJS + typeof(exports) != 'undefined' ? exports.Brush = Brush : null; +})(); diff --git a/scm-webapp/src/main/webapp/resources/syntaxhighlighter/scripts/shBrushJavaFX.js b/scm-webapp/src/main/webapp/resources/syntaxhighlighter/scripts/shBrushJavaFX.js new file mode 100644 index 0000000000..1a150a6ad3 --- /dev/null +++ b/scm-webapp/src/main/webapp/resources/syntaxhighlighter/scripts/shBrushJavaFX.js @@ -0,0 +1,58 @@ +/** + * SyntaxHighlighter + * http://alexgorbatchev.com/SyntaxHighlighter + * + * SyntaxHighlighter is donationware. If you are using it, please donate. + * http://alexgorbatchev.com/SyntaxHighlighter/donate.html + * + * @version + * 3.0.83 (July 02 2010) + * + * @copyright + * Copyright (C) 2004-2010 Alex Gorbatchev. + * + * @license + * Dual licensed under the MIT and GPL licenses. + */ +;(function() +{ + // CommonJS + typeof(require) != 'undefined' ? SyntaxHighlighter = require('shCore').SyntaxHighlighter : null; + + function Brush() + { + // Contributed by Patrick Webster + // http://patrickwebster.blogspot.com/2009/04/javafx-brush-for-syntaxhighlighter.html + var datatypes = 'Boolean Byte Character Double Duration ' + + 'Float Integer Long Number Short String Void' + ; + + var keywords = 'abstract after and as assert at before bind bound break catch class ' + + 'continue def delete else exclusive extends false finally first for from ' + + 'function if import in indexof init insert instanceof into inverse last ' + + 'lazy mixin mod nativearray new not null on or override package postinit ' + + 'protected public public-init public-read replace return reverse sizeof ' + + 'step super then this throw true try tween typeof var where while with ' + + 'attribute let private readonly static trigger' + ; + + this.regexList = [ + { regex: SyntaxHighlighter.regexLib.singleLineCComments, css: 'comments' }, + { regex: SyntaxHighlighter.regexLib.multiLineCComments, css: 'comments' }, + { regex: SyntaxHighlighter.regexLib.singleQuotedString, css: 'string' }, + { regex: SyntaxHighlighter.regexLib.doubleQuotedString, css: 'string' }, + { regex: /(-?\.?)(\b(\d*\.?\d+|\d+\.?\d*)(e[+-]?\d+)?|0x[a-f\d]+)\b\.?/gi, css: 'color2' }, // numbers + { regex: new RegExp(this.getKeywords(datatypes), 'gm'), css: 'variable' }, // datatypes + { regex: new RegExp(this.getKeywords(keywords), 'gm'), css: 'keyword' } + ]; + this.forHtmlScript(SyntaxHighlighter.regexLib.aspScriptTags); + }; + + Brush.prototype = new SyntaxHighlighter.Highlighter(); + Brush.aliases = ['jfx', 'javafx']; + + SyntaxHighlighter.brushes.JavaFX = Brush; + + // CommonJS + typeof(exports) != 'undefined' ? exports.Brush = Brush : null; +})(); diff --git a/scm-webapp/src/main/webapp/resources/syntaxhighlighter/scripts/shBrushPerl.js b/scm-webapp/src/main/webapp/resources/syntaxhighlighter/scripts/shBrushPerl.js new file mode 100644 index 0000000000..d94a2e0ec5 --- /dev/null +++ b/scm-webapp/src/main/webapp/resources/syntaxhighlighter/scripts/shBrushPerl.js @@ -0,0 +1,72 @@ +/** + * SyntaxHighlighter + * http://alexgorbatchev.com/SyntaxHighlighter + * + * SyntaxHighlighter is donationware. If you are using it, please donate. + * http://alexgorbatchev.com/SyntaxHighlighter/donate.html + * + * @version + * 3.0.83 (July 02 2010) + * + * @copyright + * Copyright (C) 2004-2010 Alex Gorbatchev. + * + * @license + * Dual licensed under the MIT and GPL licenses. + */ +;(function() +{ + // CommonJS + typeof(require) != 'undefined' ? SyntaxHighlighter = require('shCore').SyntaxHighlighter : null; + + function Brush() + { + // Contributed by David Simmons-Duffin and Marty Kube + + var funcs = + 'abs accept alarm atan2 bind binmode chdir chmod chomp chop chown chr ' + + 'chroot close closedir connect cos crypt defined delete each endgrent ' + + 'endhostent endnetent endprotoent endpwent endservent eof exec exists ' + + 'exp fcntl fileno flock fork format formline getc getgrent getgrgid ' + + 'getgrnam gethostbyaddr gethostbyname gethostent getlogin getnetbyaddr ' + + 'getnetbyname getnetent getpeername getpgrp getppid getpriority ' + + 'getprotobyname getprotobynumber getprotoent getpwent getpwnam getpwuid ' + + 'getservbyname getservbyport getservent getsockname getsockopt glob ' + + 'gmtime grep hex index int ioctl join keys kill lc lcfirst length link ' + + 'listen localtime lock log lstat map mkdir msgctl msgget msgrcv msgsnd ' + + 'oct open opendir ord pack pipe pop pos print printf prototype push ' + + 'quotemeta rand read readdir readline readlink readpipe recv rename ' + + 'reset reverse rewinddir rindex rmdir scalar seek seekdir select semctl ' + + 'semget semop send setgrent sethostent setnetent setpgrp setpriority ' + + 'setprotoent setpwent setservent setsockopt shift shmctl shmget shmread ' + + 'shmwrite shutdown sin sleep socket socketpair sort splice split sprintf ' + + 'sqrt srand stat study substr symlink syscall sysopen sysread sysseek ' + + 'system syswrite tell telldir time times tr truncate uc ucfirst umask ' + + 'undef unlink unpack unshift utime values vec wait waitpid warn write'; + + var keywords = + 'bless caller continue dbmclose dbmopen die do dump else elsif eval exit ' + + 'for foreach goto if import last local my next no our package redo ref ' + + 'require return sub tie tied unless untie until use wantarray while'; + + this.regexList = [ + { regex: new RegExp('#[^!].*$', 'gm'), css: 'comments' }, + { regex: new RegExp('^\\s*#!.*$', 'gm'), css: 'preprocessor' }, // shebang + { regex: SyntaxHighlighter.regexLib.doubleQuotedString, css: 'string' }, + { regex: SyntaxHighlighter.regexLib.singleQuotedString, css: 'string' }, + { regex: new RegExp('(\\$|@|%)\\w+', 'g'), css: 'variable' }, + { regex: new RegExp(this.getKeywords(funcs), 'gmi'), css: 'functions' }, + { regex: new RegExp(this.getKeywords(keywords), 'gm'), css: 'keyword' } + ]; + + this.forHtmlScript(SyntaxHighlighter.regexLib.phpScriptTags); + } + + Brush.prototype = new SyntaxHighlighter.Highlighter(); + Brush.aliases = ['perl', 'Perl', 'pl']; + + SyntaxHighlighter.brushes.Perl = Brush; + + // CommonJS + typeof(exports) != 'undefined' ? exports.Brush = Brush : null; +})(); diff --git a/scm-webapp/src/main/webapp/resources/syntaxhighlighter/scripts/shBrushPhp.js b/scm-webapp/src/main/webapp/resources/syntaxhighlighter/scripts/shBrushPhp.js new file mode 100644 index 0000000000..95e6e4325b --- /dev/null +++ b/scm-webapp/src/main/webapp/resources/syntaxhighlighter/scripts/shBrushPhp.js @@ -0,0 +1,88 @@ +/** + * SyntaxHighlighter + * http://alexgorbatchev.com/SyntaxHighlighter + * + * SyntaxHighlighter is donationware. If you are using it, please donate. + * http://alexgorbatchev.com/SyntaxHighlighter/donate.html + * + * @version + * 3.0.83 (July 02 2010) + * + * @copyright + * Copyright (C) 2004-2010 Alex Gorbatchev. + * + * @license + * Dual licensed under the MIT and GPL licenses. + */ +;(function() +{ + // CommonJS + typeof(require) != 'undefined' ? SyntaxHighlighter = require('shCore').SyntaxHighlighter : null; + + function Brush() + { + var funcs = 'abs acos acosh addcslashes addslashes ' + + 'array_change_key_case array_chunk array_combine array_count_values array_diff '+ + 'array_diff_assoc array_diff_key array_diff_uassoc array_diff_ukey array_fill '+ + 'array_filter array_flip array_intersect array_intersect_assoc array_intersect_key '+ + 'array_intersect_uassoc array_intersect_ukey array_key_exists array_keys array_map '+ + 'array_merge array_merge_recursive array_multisort array_pad array_pop array_product '+ + 'array_push array_rand array_reduce array_reverse array_search array_shift '+ + 'array_slice array_splice array_sum array_udiff array_udiff_assoc '+ + 'array_udiff_uassoc array_uintersect array_uintersect_assoc '+ + 'array_uintersect_uassoc array_unique array_unshift array_values array_walk '+ + 'array_walk_recursive atan atan2 atanh base64_decode base64_encode base_convert '+ + 'basename bcadd bccomp bcdiv bcmod bcmul bindec bindtextdomain bzclose bzcompress '+ + 'bzdecompress bzerrno bzerror bzerrstr bzflush bzopen bzread bzwrite ceil chdir '+ + 'checkdate checkdnsrr chgrp chmod chop chown chr chroot chunk_split class_exists '+ + 'closedir closelog copy cos cosh count count_chars date decbin dechex decoct '+ + 'deg2rad delete ebcdic2ascii echo empty end ereg ereg_replace eregi eregi_replace error_log '+ + 'error_reporting escapeshellarg escapeshellcmd eval exec exit exp explode extension_loaded '+ + 'feof fflush fgetc fgetcsv fgets fgetss file_exists file_get_contents file_put_contents '+ + 'fileatime filectime filegroup fileinode filemtime fileowner fileperms filesize filetype '+ + 'floatval flock floor flush fmod fnmatch fopen fpassthru fprintf fputcsv fputs fread fscanf '+ + 'fseek fsockopen fstat ftell ftok getallheaders getcwd getdate getenv gethostbyaddr gethostbyname '+ + 'gethostbynamel getimagesize getlastmod getmxrr getmygid getmyinode getmypid getmyuid getopt '+ + 'getprotobyname getprotobynumber getrandmax getrusage getservbyname getservbyport gettext '+ + 'gettimeofday gettype glob gmdate gmmktime ini_alter ini_get ini_get_all ini_restore ini_set '+ + 'interface_exists intval ip2long is_a is_array is_bool is_callable is_dir is_double '+ + 'is_executable is_file is_finite is_float is_infinite is_int is_integer is_link is_long '+ + 'is_nan is_null is_numeric is_object is_readable is_real is_resource is_scalar is_soap_fault '+ + 'is_string is_subclass_of is_uploaded_file is_writable is_writeable mkdir mktime nl2br '+ + 'parse_ini_file parse_str parse_url passthru pathinfo print readlink realpath rewind rewinddir rmdir '+ + 'round str_ireplace str_pad str_repeat str_replace str_rot13 str_shuffle str_split '+ + 'str_word_count strcasecmp strchr strcmp strcoll strcspn strftime strip_tags stripcslashes '+ + 'stripos stripslashes stristr strlen strnatcasecmp strnatcmp strncasecmp strncmp strpbrk '+ + 'strpos strptime strrchr strrev strripos strrpos strspn strstr strtok strtolower strtotime '+ + 'strtoupper strtr strval substr substr_compare'; + + var keywords = 'abstract and array as break case catch cfunction class clone const continue declare default die do ' + + 'else elseif enddeclare endfor endforeach endif endswitch endwhile extends final for foreach ' + + 'function include include_once global goto if implements interface instanceof namespace new ' + + 'old_function or private protected public return require require_once static switch ' + + 'throw try use var while xor '; + + var constants = '__FILE__ __LINE__ __METHOD__ __FUNCTION__ __CLASS__'; + + this.regexList = [ + { regex: SyntaxHighlighter.regexLib.singleLineCComments, css: 'comments' }, // one line comments + { regex: SyntaxHighlighter.regexLib.multiLineCComments, css: 'comments' }, // multiline comments + { regex: SyntaxHighlighter.regexLib.doubleQuotedString, css: 'string' }, // double quoted strings + { regex: SyntaxHighlighter.regexLib.singleQuotedString, css: 'string' }, // single quoted strings + { regex: /\$\w+/g, css: 'variable' }, // variables + { regex: new RegExp(this.getKeywords(funcs), 'gmi'), css: 'functions' }, // common functions + { regex: new RegExp(this.getKeywords(constants), 'gmi'), css: 'constants' }, // constants + { regex: new RegExp(this.getKeywords(keywords), 'gm'), css: 'keyword' } // keyword + ]; + + this.forHtmlScript(SyntaxHighlighter.regexLib.phpScriptTags); + }; + + Brush.prototype = new SyntaxHighlighter.Highlighter(); + Brush.aliases = ['php']; + + SyntaxHighlighter.brushes.Php = Brush; + + // CommonJS + typeof(exports) != 'undefined' ? exports.Brush = Brush : null; +})(); diff --git a/scm-webapp/src/main/webapp/resources/syntaxhighlighter/scripts/shBrushPlain.js b/scm-webapp/src/main/webapp/resources/syntaxhighlighter/scripts/shBrushPlain.js new file mode 100644 index 0000000000..9f7d9e90c3 --- /dev/null +++ b/scm-webapp/src/main/webapp/resources/syntaxhighlighter/scripts/shBrushPlain.js @@ -0,0 +1,33 @@ +/** + * SyntaxHighlighter + * http://alexgorbatchev.com/SyntaxHighlighter + * + * SyntaxHighlighter is donationware. If you are using it, please donate. + * http://alexgorbatchev.com/SyntaxHighlighter/donate.html + * + * @version + * 3.0.83 (July 02 2010) + * + * @copyright + * Copyright (C) 2004-2010 Alex Gorbatchev. + * + * @license + * Dual licensed under the MIT and GPL licenses. + */ +;(function() +{ + // CommonJS + typeof(require) != 'undefined' ? SyntaxHighlighter = require('shCore').SyntaxHighlighter : null; + + function Brush() + { + }; + + Brush.prototype = new SyntaxHighlighter.Highlighter(); + Brush.aliases = ['text', 'plain']; + + SyntaxHighlighter.brushes.Plain = Brush; + + // CommonJS + typeof(exports) != 'undefined' ? exports.Brush = Brush : null; +})(); diff --git a/scm-webapp/src/main/webapp/resources/syntaxhighlighter/scripts/shBrushPowerShell.js b/scm-webapp/src/main/webapp/resources/syntaxhighlighter/scripts/shBrushPowerShell.js new file mode 100644 index 0000000000..0be1752968 --- /dev/null +++ b/scm-webapp/src/main/webapp/resources/syntaxhighlighter/scripts/shBrushPowerShell.js @@ -0,0 +1,74 @@ +/** + * SyntaxHighlighter + * http://alexgorbatchev.com/SyntaxHighlighter + * + * SyntaxHighlighter is donationware. If you are using it, please donate. + * http://alexgorbatchev.com/SyntaxHighlighter/donate.html + * + * @version + * 3.0.83 (July 02 2010) + * + * @copyright + * Copyright (C) 2004-2010 Alex Gorbatchev. + * + * @license + * Dual licensed under the MIT and GPL licenses. + */ +;(function() +{ + // CommonJS + typeof(require) != 'undefined' ? SyntaxHighlighter = require('shCore').SyntaxHighlighter : null; + + function Brush() + { + // Contributes by B.v.Zanten, Getronics + // http://confluence.atlassian.com/display/CONFEXT/New+Code+Macro + + var keywords = 'Add-Content Add-History Add-Member Add-PSSnapin Clear(-Content)? Clear-Item ' + + 'Clear-ItemProperty Clear-Variable Compare-Object ConvertFrom-SecureString Convert-Path ' + + 'ConvertTo-Html ConvertTo-SecureString Copy(-Item)? Copy-ItemProperty Export-Alias ' + + 'Export-Clixml Export-Console Export-Csv ForEach(-Object)? Format-Custom Format-List ' + + 'Format-Table Format-Wide Get-Acl Get-Alias Get-AuthenticodeSignature Get-ChildItem Get-Command ' + + 'Get-Content Get-Credential Get-Culture Get-Date Get-EventLog Get-ExecutionPolicy ' + + 'Get-Help Get-History Get-Host Get-Item Get-ItemProperty Get-Location Get-Member ' + + 'Get-PfxCertificate Get-Process Get-PSDrive Get-PSProvider Get-PSSnapin Get-Service ' + + 'Get-TraceSource Get-UICulture Get-Unique Get-Variable Get-WmiObject Group-Object ' + + 'Import-Alias Import-Clixml Import-Csv Invoke-Expression Invoke-History Invoke-Item ' + + 'Join-Path Measure-Command Measure-Object Move(-Item)? Move-ItemProperty New-Alias ' + + 'New-Item New-ItemProperty New-Object New-PSDrive New-Service New-TimeSpan ' + + 'New-Variable Out-Default Out-File Out-Host Out-Null Out-Printer Out-String Pop-Location ' + + 'Push-Location Read-Host Remove-Item Remove-ItemProperty Remove-PSDrive Remove-PSSnapin ' + + 'Remove-Variable Rename-Item Rename-ItemProperty Resolve-Path Restart-Service Resume-Service ' + + 'Select-Object Select-String Set-Acl Set-Alias Set-AuthenticodeSignature Set-Content ' + + 'Set-Date Set-ExecutionPolicy Set-Item Set-ItemProperty Set-Location Set-PSDebug ' + + 'Set-Service Set-TraceSource Set(-Variable)? Sort-Object Split-Path Start-Service ' + + 'Start-Sleep Start-Transcript Stop-Process Stop-Service Stop-Transcript Suspend-Service ' + + 'Tee-Object Test-Path Trace-Command Update-FormatData Update-TypeData Where(-Object)? ' + + 'Write-Debug Write-Error Write(-Host)? Write-Output Write-Progress Write-Verbose Write-Warning'; + var alias = 'ac asnp clc cli clp clv cpi cpp cvpa diff epal epcsv fc fl ' + + 'ft fw gal gc gci gcm gdr ghy gi gl gm gp gps group gsv ' + + 'gsnp gu gv gwmi iex ihy ii ipal ipcsv mi mp nal ndr ni nv oh rdr ' + + 'ri rni rnp rp rsnp rv rvpa sal sasv sc select si sl sleep sort sp ' + + 'spps spsv sv tee cat cd cp h history kill lp ls ' + + 'mount mv popd ps pushd pwd r rm rmdir echo cls chdir del dir ' + + 'erase rd ren type % \\?'; + + this.regexList = [ + { regex: /#.*$/gm, css: 'comments' }, // one line comments + { regex: /\$[a-zA-Z0-9]+\b/g, css: 'value' }, // variables $Computer1 + { regex: /\-[a-zA-Z]+\b/g, css: 'keyword' }, // Operators -not -and -eq + { regex: SyntaxHighlighter.regexLib.doubleQuotedString, css: 'string' }, // strings + { regex: SyntaxHighlighter.regexLib.singleQuotedString, css: 'string' }, // strings + { regex: new RegExp(this.getKeywords(keywords), 'gmi'), css: 'keyword' }, + { regex: new RegExp(this.getKeywords(alias), 'gmi'), css: 'keyword' } + ]; + }; + + Brush.prototype = new SyntaxHighlighter.Highlighter(); + Brush.aliases = ['powershell', 'ps']; + + SyntaxHighlighter.brushes.PowerShell = Brush; + + // CommonJS + typeof(exports) != 'undefined' ? exports.Brush = Brush : null; +})(); diff --git a/scm-webapp/src/main/webapp/resources/syntaxhighlighter/scripts/shBrushPython.js b/scm-webapp/src/main/webapp/resources/syntaxhighlighter/scripts/shBrushPython.js new file mode 100644 index 0000000000..ce77462975 --- /dev/null +++ b/scm-webapp/src/main/webapp/resources/syntaxhighlighter/scripts/shBrushPython.js @@ -0,0 +1,64 @@ +/** + * SyntaxHighlighter + * http://alexgorbatchev.com/SyntaxHighlighter + * + * SyntaxHighlighter is donationware. If you are using it, please donate. + * http://alexgorbatchev.com/SyntaxHighlighter/donate.html + * + * @version + * 3.0.83 (July 02 2010) + * + * @copyright + * Copyright (C) 2004-2010 Alex Gorbatchev. + * + * @license + * Dual licensed under the MIT and GPL licenses. + */ +;(function() +{ + // CommonJS + typeof(require) != 'undefined' ? SyntaxHighlighter = require('shCore').SyntaxHighlighter : null; + + function Brush() + { + // Contributed by Gheorghe Milas and Ahmad Sherif + + var keywords = 'and assert break class continue def del elif else ' + + 'except exec finally for from global if import in is ' + + 'lambda not or pass print raise return try yield while'; + + var funcs = '__import__ abs all any apply basestring bin bool buffer callable ' + + 'chr classmethod cmp coerce compile complex delattr dict dir ' + + 'divmod enumerate eval execfile file filter float format frozenset ' + + 'getattr globals hasattr hash help hex id input int intern ' + + 'isinstance issubclass iter len list locals long map max min next ' + + 'object oct open ord pow print property range raw_input reduce ' + + 'reload repr reversed round set setattr slice sorted staticmethod ' + + 'str sum super tuple type type unichr unicode vars xrange zip'; + + var special = 'None True False self cls class_'; + + this.regexList = [ + { regex: SyntaxHighlighter.regexLib.singleLinePerlComments, css: 'comments' }, + { regex: /^\s*@\w+/gm, css: 'decorator' }, + { regex: /(['\"]{3})([^\1])*?\1/gm, css: 'comments' }, + { regex: /"(?!")(?:\.|\\\"|[^\""\n])*"/gm, css: 'string' }, + { regex: /'(?!')(?:\.|(\\\')|[^\''\n])*'/gm, css: 'string' }, + { regex: /\+|\-|\*|\/|\%|=|==/gm, css: 'keyword' }, + { regex: /\b\d+\.?\w*/g, css: 'value' }, + { regex: new RegExp(this.getKeywords(funcs), 'gmi'), css: 'functions' }, + { regex: new RegExp(this.getKeywords(keywords), 'gm'), css: 'keyword' }, + { regex: new RegExp(this.getKeywords(special), 'gm'), css: 'color1' } + ]; + + this.forHtmlScript(SyntaxHighlighter.regexLib.aspScriptTags); + }; + + Brush.prototype = new SyntaxHighlighter.Highlighter(); + Brush.aliases = ['py', 'python']; + + SyntaxHighlighter.brushes.Python = Brush; + + // CommonJS + typeof(exports) != 'undefined' ? exports.Brush = Brush : null; +})(); diff --git a/scm-webapp/src/main/webapp/resources/syntaxhighlighter/scripts/shBrushRuby.js b/scm-webapp/src/main/webapp/resources/syntaxhighlighter/scripts/shBrushRuby.js new file mode 100644 index 0000000000..ff82130a7a --- /dev/null +++ b/scm-webapp/src/main/webapp/resources/syntaxhighlighter/scripts/shBrushRuby.js @@ -0,0 +1,55 @@ +/** + * SyntaxHighlighter + * http://alexgorbatchev.com/SyntaxHighlighter + * + * SyntaxHighlighter is donationware. If you are using it, please donate. + * http://alexgorbatchev.com/SyntaxHighlighter/donate.html + * + * @version + * 3.0.83 (July 02 2010) + * + * @copyright + * Copyright (C) 2004-2010 Alex Gorbatchev. + * + * @license + * Dual licensed under the MIT and GPL licenses. + */ +;(function() +{ + // CommonJS + typeof(require) != 'undefined' ? SyntaxHighlighter = require('shCore').SyntaxHighlighter : null; + + function Brush() + { + // Contributed by Erik Peterson. + + var keywords = 'alias and BEGIN begin break case class def define_method defined do each else elsif ' + + 'END end ensure false for if in module new next nil not or raise redo rescue retry return ' + + 'self super then throw true undef unless until when while yield'; + + var builtins = 'Array Bignum Binding Class Continuation Dir Exception FalseClass File::Stat File Fixnum Fload ' + + 'Hash Integer IO MatchData Method Module NilClass Numeric Object Proc Range Regexp String Struct::TMS Symbol ' + + 'ThreadGroup Thread Time TrueClass'; + + this.regexList = [ + { regex: SyntaxHighlighter.regexLib.singleLinePerlComments, css: 'comments' }, // one line comments + { regex: SyntaxHighlighter.regexLib.doubleQuotedString, css: 'string' }, // double quoted strings + { regex: SyntaxHighlighter.regexLib.singleQuotedString, css: 'string' }, // single quoted strings + { regex: /\b[A-Z0-9_]+\b/g, css: 'constants' }, // constants + { regex: /:[a-z][A-Za-z0-9_]*/g, css: 'color2' }, // symbols + { regex: /(\$|@@|@)\w+/g, css: 'variable bold' }, // $global, @instance, and @@class variables + { regex: new RegExp(this.getKeywords(keywords), 'gm'), css: 'keyword' }, // keywords + { regex: new RegExp(this.getKeywords(builtins), 'gm'), css: 'color1' } // builtins + ]; + + this.forHtmlScript(SyntaxHighlighter.regexLib.aspScriptTags); + }; + + Brush.prototype = new SyntaxHighlighter.Highlighter(); + Brush.aliases = ['ruby', 'rails', 'ror', 'rb']; + + SyntaxHighlighter.brushes.Ruby = Brush; + + // CommonJS + typeof(exports) != 'undefined' ? exports.Brush = Brush : null; +})(); diff --git a/scm-webapp/src/main/webapp/resources/syntaxhighlighter/scripts/shBrushSass.js b/scm-webapp/src/main/webapp/resources/syntaxhighlighter/scripts/shBrushSass.js new file mode 100644 index 0000000000..aa04da0996 --- /dev/null +++ b/scm-webapp/src/main/webapp/resources/syntaxhighlighter/scripts/shBrushSass.js @@ -0,0 +1,94 @@ +/** + * SyntaxHighlighter + * http://alexgorbatchev.com/SyntaxHighlighter + * + * SyntaxHighlighter is donationware. If you are using it, please donate. + * http://alexgorbatchev.com/SyntaxHighlighter/donate.html + * + * @version + * 3.0.83 (July 02 2010) + * + * @copyright + * Copyright (C) 2004-2010 Alex Gorbatchev. + * + * @license + * Dual licensed under the MIT and GPL licenses. + */ +;(function() +{ + // CommonJS + typeof(require) != 'undefined' ? SyntaxHighlighter = require('shCore').SyntaxHighlighter : null; + + function Brush() + { + function getKeywordsCSS(str) + { + return '\\b([a-z_]|)' + str.replace(/ /g, '(?=:)\\b|\\b([a-z_\\*]|\\*|)') + '(?=:)\\b'; + }; + + function getValuesCSS(str) + { + return '\\b' + str.replace(/ /g, '(?!-)(?!:)\\b|\\b()') + '\:\\b'; + }; + + var keywords = 'ascent azimuth background-attachment background-color background-image background-position ' + + 'background-repeat background baseline bbox border-collapse border-color border-spacing border-style border-top ' + + 'border-right border-bottom border-left border-top-color border-right-color border-bottom-color border-left-color ' + + 'border-top-style border-right-style border-bottom-style border-left-style border-top-width border-right-width ' + + 'border-bottom-width border-left-width border-width border bottom cap-height caption-side centerline clear clip color ' + + 'content counter-increment counter-reset cue-after cue-before cue cursor definition-src descent direction display ' + + 'elevation empty-cells float font-size-adjust font-family font-size font-stretch font-style font-variant font-weight font ' + + 'height left letter-spacing line-height list-style-image list-style-position list-style-type list-style margin-top ' + + 'margin-right margin-bottom margin-left margin marker-offset marks mathline max-height max-width min-height min-width orphans ' + + 'outline-color outline-style outline-width outline overflow padding-top padding-right padding-bottom padding-left padding page ' + + 'page-break-after page-break-before page-break-inside pause pause-after pause-before pitch pitch-range play-during position ' + + 'quotes right richness size slope src speak-header speak-numeral speak-punctuation speak speech-rate stemh stemv stress ' + + 'table-layout text-align top text-decoration text-indent text-shadow text-transform unicode-bidi unicode-range units-per-em ' + + 'vertical-align visibility voice-family volume white-space widows width widths word-spacing x-height z-index'; + + var values = 'above absolute all always aqua armenian attr aural auto avoid baseline behind below bidi-override black blink block blue bold bolder '+ + 'both bottom braille capitalize caption center center-left center-right circle close-quote code collapse compact condensed '+ + 'continuous counter counters crop cross crosshair cursive dashed decimal decimal-leading-zero digits disc dotted double '+ + 'embed embossed e-resize expanded extra-condensed extra-expanded fantasy far-left far-right fast faster fixed format fuchsia '+ + 'gray green groove handheld hebrew help hidden hide high higher icon inline-table inline inset inside invert italic '+ + 'justify landscape large larger left-side left leftwards level lighter lime line-through list-item local loud lower-alpha '+ + 'lowercase lower-greek lower-latin lower-roman lower low ltr marker maroon medium message-box middle mix move narrower '+ + 'navy ne-resize no-close-quote none no-open-quote no-repeat normal nowrap n-resize nw-resize oblique olive once open-quote outset '+ + 'outside overline pointer portrait pre print projection purple red relative repeat repeat-x repeat-y rgb ridge right right-side '+ + 'rightwards rtl run-in screen scroll semi-condensed semi-expanded separate se-resize show silent silver slower slow '+ + 'small small-caps small-caption smaller soft solid speech spell-out square s-resize static status-bar sub super sw-resize '+ + 'table-caption table-cell table-column table-column-group table-footer-group table-header-group table-row table-row-group teal '+ + 'text-bottom text-top thick thin top transparent tty tv ultra-condensed ultra-expanded underline upper-alpha uppercase upper-latin '+ + 'upper-roman url visible wait white wider w-resize x-fast x-high x-large x-loud x-low x-slow x-small x-soft xx-large xx-small yellow'; + + var fonts = '[mM]onospace [tT]ahoma [vV]erdana [aA]rial [hH]elvetica [sS]ans-serif [sS]erif [cC]ourier mono sans serif'; + + var statements = '!important !default'; + var preprocessor = '@import @extend @debug @warn @if @for @while @mixin @include'; + + var r = SyntaxHighlighter.regexLib; + + this.regexList = [ + { regex: r.multiLineCComments, css: 'comments' }, // multiline comments + { regex: r.singleLineCComments, css: 'comments' }, // singleline comments + { regex: r.doubleQuotedString, css: 'string' }, // double quoted strings + { regex: r.singleQuotedString, css: 'string' }, // single quoted strings + { regex: /\#[a-fA-F0-9]{3,6}/g, css: 'value' }, // html colors + { regex: /\b(-?\d+)(\.\d+)?(px|em|pt|\:|\%|)\b/g, css: 'value' }, // sizes + { regex: /\$\w+/g, css: 'variable' }, // variables + { regex: new RegExp(this.getKeywords(statements), 'g'), css: 'color3' }, // statements + { regex: new RegExp(this.getKeywords(preprocessor), 'g'), css: 'preprocessor' }, // preprocessor + { regex: new RegExp(getKeywordsCSS(keywords), 'gm'), css: 'keyword' }, // keywords + { regex: new RegExp(getValuesCSS(values), 'g'), css: 'value' }, // values + { regex: new RegExp(this.getKeywords(fonts), 'g'), css: 'color1' } // fonts + ]; + }; + + Brush.prototype = new SyntaxHighlighter.Highlighter(); + Brush.aliases = ['sass', 'scss']; + + SyntaxHighlighter.brushes.Sass = Brush; + + // CommonJS + typeof(exports) != 'undefined' ? exports.Brush = Brush : null; +})(); diff --git a/scm-webapp/src/main/webapp/resources/syntaxhighlighter/scripts/shBrushScala.js b/scm-webapp/src/main/webapp/resources/syntaxhighlighter/scripts/shBrushScala.js new file mode 100644 index 0000000000..4b0b6f04d2 --- /dev/null +++ b/scm-webapp/src/main/webapp/resources/syntaxhighlighter/scripts/shBrushScala.js @@ -0,0 +1,51 @@ +/** + * SyntaxHighlighter + * http://alexgorbatchev.com/SyntaxHighlighter + * + * SyntaxHighlighter is donationware. If you are using it, please donate. + * http://alexgorbatchev.com/SyntaxHighlighter/donate.html + * + * @version + * 3.0.83 (July 02 2010) + * + * @copyright + * Copyright (C) 2004-2010 Alex Gorbatchev. + * + * @license + * Dual licensed under the MIT and GPL licenses. + */ +;(function() +{ + // CommonJS + typeof(require) != 'undefined' ? SyntaxHighlighter = require('shCore').SyntaxHighlighter : null; + + function Brush() + { + // Contributed by Yegor Jbanov and David Bernard. + + var keywords = 'val sealed case def true trait implicit forSome import match object null finally super ' + + 'override try lazy for var catch throw type extends class while with new final yield abstract ' + + 'else do if return protected private this package false'; + + var keyops = '[_:=><%#@]+'; + + this.regexList = [ + { regex: SyntaxHighlighter.regexLib.singleLineCComments, css: 'comments' }, // one line comments + { regex: SyntaxHighlighter.regexLib.multiLineCComments, css: 'comments' }, // multiline comments + { regex: SyntaxHighlighter.regexLib.multiLineSingleQuotedString, css: 'string' }, // multi-line strings + { regex: SyntaxHighlighter.regexLib.multiLineDoubleQuotedString, css: 'string' }, // double-quoted string + { regex: SyntaxHighlighter.regexLib.singleQuotedString, css: 'string' }, // strings + { regex: /0x[a-f0-9]+|\d+(\.\d+)?/gi, css: 'value' }, // numbers + { regex: new RegExp(this.getKeywords(keywords), 'gm'), css: 'keyword' }, // keywords + { regex: new RegExp(keyops, 'gm'), css: 'keyword' } // scala keyword + ]; + } + + Brush.prototype = new SyntaxHighlighter.Highlighter(); + Brush.aliases = ['scala']; + + SyntaxHighlighter.brushes.Scala = Brush; + + // CommonJS + typeof(exports) != 'undefined' ? exports.Brush = Brush : null; +})(); diff --git a/scm-webapp/src/main/webapp/resources/syntaxhighlighter/scripts/shBrushSql.js b/scm-webapp/src/main/webapp/resources/syntaxhighlighter/scripts/shBrushSql.js new file mode 100644 index 0000000000..5c2cd8806f --- /dev/null +++ b/scm-webapp/src/main/webapp/resources/syntaxhighlighter/scripts/shBrushSql.js @@ -0,0 +1,66 @@ +/** + * SyntaxHighlighter + * http://alexgorbatchev.com/SyntaxHighlighter + * + * SyntaxHighlighter is donationware. If you are using it, please donate. + * http://alexgorbatchev.com/SyntaxHighlighter/donate.html + * + * @version + * 3.0.83 (July 02 2010) + * + * @copyright + * Copyright (C) 2004-2010 Alex Gorbatchev. + * + * @license + * Dual licensed under the MIT and GPL licenses. + */ +;(function() +{ + // CommonJS + typeof(require) != 'undefined' ? SyntaxHighlighter = require('shCore').SyntaxHighlighter : null; + + function Brush() + { + var funcs = 'abs avg case cast coalesce convert count current_timestamp ' + + 'current_user day isnull left lower month nullif replace right ' + + 'session_user space substring sum system_user upper user year'; + + var keywords = 'absolute action add after alter as asc at authorization begin bigint ' + + 'binary bit by cascade char character check checkpoint close collate ' + + 'column commit committed connect connection constraint contains continue ' + + 'create cube current current_date current_time cursor database date ' + + 'deallocate dec decimal declare default delete desc distinct double drop ' + + 'dynamic else end end-exec escape except exec execute false fetch first ' + + 'float for force foreign forward free from full function global goto grant ' + + 'group grouping having hour ignore index inner insensitive insert instead ' + + 'int integer intersect into is isolation key last level load local max min ' + + 'minute modify move name national nchar next no numeric of off on only ' + + 'open option order out output partial password precision prepare primary ' + + 'prior privileges procedure public read real references relative repeatable ' + + 'restrict return returns revoke rollback rollup rows rule schema scroll ' + + 'second section select sequence serializable set size smallint static ' + + 'statistics table temp temporary then time timestamp to top transaction ' + + 'translation trigger true truncate uncommitted union unique update values ' + + 'varchar varying view when where with work'; + + var operators = 'all and any between cross in join like not null or outer some'; + + this.regexList = [ + { regex: /--(.*)$/gm, css: 'comments' }, // one line and multiline comments + { regex: SyntaxHighlighter.regexLib.multiLineDoubleQuotedString, css: 'string' }, // double quoted strings + { regex: SyntaxHighlighter.regexLib.multiLineSingleQuotedString, css: 'string' }, // single quoted strings + { regex: new RegExp(this.getKeywords(funcs), 'gmi'), css: 'color2' }, // functions + { regex: new RegExp(this.getKeywords(operators), 'gmi'), css: 'color1' }, // operators and such + { regex: new RegExp(this.getKeywords(keywords), 'gmi'), css: 'keyword' } // keyword + ]; + }; + + Brush.prototype = new SyntaxHighlighter.Highlighter(); + Brush.aliases = ['sql']; + + SyntaxHighlighter.brushes.Sql = Brush; + + // CommonJS + typeof(exports) != 'undefined' ? exports.Brush = Brush : null; +})(); + diff --git a/scm-webapp/src/main/webapp/resources/syntaxhighlighter/scripts/shBrushVb.js b/scm-webapp/src/main/webapp/resources/syntaxhighlighter/scripts/shBrushVb.js new file mode 100644 index 0000000000..be845dc0b3 --- /dev/null +++ b/scm-webapp/src/main/webapp/resources/syntaxhighlighter/scripts/shBrushVb.js @@ -0,0 +1,56 @@ +/** + * SyntaxHighlighter + * http://alexgorbatchev.com/SyntaxHighlighter + * + * SyntaxHighlighter is donationware. If you are using it, please donate. + * http://alexgorbatchev.com/SyntaxHighlighter/donate.html + * + * @version + * 3.0.83 (July 02 2010) + * + * @copyright + * Copyright (C) 2004-2010 Alex Gorbatchev. + * + * @license + * Dual licensed under the MIT and GPL licenses. + */ +;(function() +{ + // CommonJS + typeof(require) != 'undefined' ? SyntaxHighlighter = require('shCore').SyntaxHighlighter : null; + + function Brush() + { + var keywords = 'AddHandler AddressOf AndAlso Alias And Ansi As Assembly Auto ' + + 'Boolean ByRef Byte ByVal Call Case Catch CBool CByte CChar CDate ' + + 'CDec CDbl Char CInt Class CLng CObj Const CShort CSng CStr CType ' + + 'Date Decimal Declare Default Delegate Dim DirectCast Do Double Each ' + + 'Else ElseIf End Enum Erase Error Event Exit False Finally For Friend ' + + 'Function Get GetType GoSub GoTo Handles If Implements Imports In ' + + 'Inherits Integer Interface Is Let Lib Like Long Loop Me Mod Module ' + + 'MustInherit MustOverride MyBase MyClass Namespace New Next Not Nothing ' + + 'NotInheritable NotOverridable Object On Option Optional Or OrElse ' + + 'Overloads Overridable Overrides ParamArray Preserve Private Property ' + + 'Protected Public RaiseEvent ReadOnly ReDim REM RemoveHandler Resume ' + + 'Return Select Set Shadows Shared Short Single Static Step Stop String ' + + 'Structure Sub SyncLock Then Throw To True Try TypeOf Unicode Until ' + + 'Variant When While With WithEvents WriteOnly Xor'; + + this.regexList = [ + { regex: /'.*$/gm, css: 'comments' }, // one line comments + { regex: SyntaxHighlighter.regexLib.doubleQuotedString, css: 'string' }, // strings + { regex: /^\s*#.*$/gm, css: 'preprocessor' }, // preprocessor tags like #region and #endregion + { regex: new RegExp(this.getKeywords(keywords), 'gm'), css: 'keyword' } // vb keyword + ]; + + this.forHtmlScript(SyntaxHighlighter.regexLib.aspScriptTags); + }; + + Brush.prototype = new SyntaxHighlighter.Highlighter(); + Brush.aliases = ['vb', 'vbnet']; + + SyntaxHighlighter.brushes.Vb = Brush; + + // CommonJS + typeof(exports) != 'undefined' ? exports.Brush = Brush : null; +})(); diff --git a/scm-webapp/src/main/webapp/resources/syntaxhighlighter/scripts/shBrushXml.js b/scm-webapp/src/main/webapp/resources/syntaxhighlighter/scripts/shBrushXml.js new file mode 100644 index 0000000000..69d9fd0b1f --- /dev/null +++ b/scm-webapp/src/main/webapp/resources/syntaxhighlighter/scripts/shBrushXml.js @@ -0,0 +1,69 @@ +/** + * SyntaxHighlighter + * http://alexgorbatchev.com/SyntaxHighlighter + * + * SyntaxHighlighter is donationware. If you are using it, please donate. + * http://alexgorbatchev.com/SyntaxHighlighter/donate.html + * + * @version + * 3.0.83 (July 02 2010) + * + * @copyright + * Copyright (C) 2004-2010 Alex Gorbatchev. + * + * @license + * Dual licensed under the MIT and GPL licenses. + */ +;(function() +{ + // CommonJS + typeof(require) != 'undefined' ? SyntaxHighlighter = require('shCore').SyntaxHighlighter : null; + + function Brush() + { + function process(match, regexInfo) + { + var constructor = SyntaxHighlighter.Match, + code = match[0], + tag = new XRegExp('(<|<)[\\s\\/\\?]*(?[:\\w-\\.]+)', 'xg').exec(code), + result = [] + ; + + if (match.attributes != null) + { + var attributes, + regex = new XRegExp('(? [\\w:\\-\\.]+)' + + '\\s*=\\s*' + + '(? ".*?"|\'.*?\'|\\w+)', + 'xg'); + + while ((attributes = regex.exec(code)) != null) + { + result.push(new constructor(attributes.name, match.index + attributes.index, 'color1')); + result.push(new constructor(attributes.value, match.index + attributes.index + attributes[0].indexOf(attributes.value), 'string')); + } + } + + if (tag != null) + result.push( + new constructor(tag.name, match.index + tag[0].indexOf(tag.name), 'keyword') + ); + + return result; + } + + this.regexList = [ + { regex: new XRegExp('(\\<|<)\\!\\[[\\w\\s]*?\\[(.|\\s)*?\\]\\](\\>|>)', 'gm'), css: 'color2' }, // + { regex: SyntaxHighlighter.regexLib.xmlComments, css: 'comments' }, // + { regex: new XRegExp('(<|<)[\\s\\/\\?]*(\\w+)(?.*?)[\\s\\/\\?]*(>|>)', 'sg'), func: process } + ]; + }; + + Brush.prototype = new SyntaxHighlighter.Highlighter(); + Brush.aliases = ['xml', 'xhtml', 'xslt', 'html']; + + SyntaxHighlighter.brushes.Xml = Brush; + + // CommonJS + typeof(exports) != 'undefined' ? exports.Brush = Brush : null; +})(); diff --git a/scm-webapp/src/main/webapp/resources/syntaxhighlighter/scripts/shCore.js b/scm-webapp/src/main/webapp/resources/syntaxhighlighter/scripts/shCore.js new file mode 100644 index 0000000000..b47b645472 --- /dev/null +++ b/scm-webapp/src/main/webapp/resources/syntaxhighlighter/scripts/shCore.js @@ -0,0 +1,17 @@ +/** + * SyntaxHighlighter + * http://alexgorbatchev.com/SyntaxHighlighter + * + * SyntaxHighlighter is donationware. If you are using it, please donate. + * http://alexgorbatchev.com/SyntaxHighlighter/donate.html + * + * @version + * 3.0.83 (July 02 2010) + * + * @copyright + * Copyright (C) 2004-2010 Alex Gorbatchev. + * + * @license + * Dual licensed under the MIT and GPL licenses. + */ +eval(function(p,a,c,k,e,d){e=function(c){return(c35?String.fromCharCode(c+29):c.toString(36))};if(!''.replace(/^/,String)){while(c--){d[e(c)]=k[c]||e(c)}k=[function(e){return d[e]}];e=function(){return'\\w+'};c=1};while(c--){if(k[c]){p=p.replace(new RegExp('\\b'+e(c)+'\\b','g'),k[c])}}return p}('K M;I(M)1S 2U("2a\'t 4k M 4K 2g 3l 4G 4H");(6(){6 r(f,e){I(!M.1R(f))1S 3m("3s 15 4R");K a=f.1w;f=M(f.1m,t(f)+(e||""));I(a)f.1w={1m:a.1m,19:a.19?a.19.1a(0):N};H f}6 t(f){H(f.1J?"g":"")+(f.4s?"i":"")+(f.4p?"m":"")+(f.4v?"x":"")+(f.3n?"y":"")}6 B(f,e,a,b){K c=u.L,d,h,g;v=R;5K{O(;c--;){g=u[c];I(a&g.3r&&(!g.2p||g.2p.W(b))){g.2q.12=e;I((h=g.2q.X(f))&&h.P===e){d={3k:g.2b.W(b,h,a),1C:h};1N}}}}5v(i){1S i}5q{v=11}H d}6 p(f,e,a){I(3b.Z.1i)H f.1i(e,a);O(a=a||0;a-1},3d:6(g){e+=g}};c1&&p(e,"")>-1){a=15(J.1m,n.Q.W(t(J),"g",""));n.Q.W(f.1a(e.P),a,6(){O(K c=1;c<14.L-2;c++)I(14[c]===1d)e[c]=1d})}I(J.1w&&J.1w.19)O(K b=1;be.P&&J.12--}H e};I(!D)15.Z.1A=6(f){(f=n.X.W(J,f))&&J.1J&&!f[0].L&&J.12>f.P&&J.12--;H!!f};1r.Z.1C=6(f){M.1R(f)||(f=15(f));I(f.1J){K e=n.1C.1p(J,14);f.12=0;H e}H f.X(J)};1r.Z.Q=6(f,e){K a=M.1R(f),b,c;I(a&&1j e.58()==="3f"&&e.1i("${")===-1&&y)H n.Q.1p(J,14);I(a){I(f.1w)b=f.1w.19}Y f+="";I(1j e==="6")c=n.Q.W(J,f,6(){I(b){14[0]=1f 1r(14[0]);O(K d=0;dd.L-3;){i=1r.Z.1a.W(g,-1)+i;g=1Q.3i(g/10)}H(g?d[g]||"":"$")+i}Y{g=+i;I(g<=d.L-3)H d[g];g=b?p(b,i):-1;H g>-1?d[g+1]:h}})})}I(a&&f.1J)f.12=0;H c};1r.Z.1e=6(f,e){I(!M.1R(f))H n.1e.1p(J,14);K a=J+"",b=[],c=0,d,h;I(e===1d||+e<0)e=5D;Y{e=1Q.3i(+e);I(!e)H[]}O(f=M.3c(f);d=f.X(a);){I(f.12>c){b.U(a.1a(c,d.P));d.L>1&&d.P=e)1N}f.12===d.P&&f.12++}I(c===a.L){I(!n.1A.W(f,"")||h)b.U("")}Y b.U(a.1a(c));H b.L>e?b.1a(0,e):b};M.1h(/\\(\\?#[^)]*\\)/,6(f){H n.1A.W(A,f.2S.1a(f.P+f[0].L))?"":"(?:)"});M.1h(/\\((?!\\?)/,6(){J.19.U(N);H"("});M.1h(/\\(\\?<([$\\w]+)>/,6(f){J.19.U(f[1]);J.2N=R;H"("});M.1h(/\\\\k<([\\w$]+)>/,6(f){K e=p(J.19,f[1]);H e>-1?"\\\\"+(e+1)+(3R(f.2S.3a(f.P+f[0].L))?"":"(?:)"):f[0]});M.1h(/\\[\\^?]/,6(f){H f[0]==="[]"?"\\\\b\\\\B":"[\\\\s\\\\S]"});M.1h(/^\\(\\?([5A]+)\\)/,6(f){J.3d(f[1]);H""});M.1h(/(?:\\s+|#.*)+/,6(f){H n.1A.W(A,f.2S.1a(f.P+f[0].L))?"":"(?:)"},M.1B,6(){H J.2K("x")});M.1h(/\\./,6(){H"[\\\\s\\\\S]"},M.1B,6(){H J.2K("s")})})();1j 2e!="1d"&&(2e.M=M);K 1v=6(){6 r(a,b){a.1l.1i(b)!=-1||(a.1l+=" "+b)}6 t(a){H a.1i("3e")==0?a:"3e"+a}6 B(a){H e.1Y.2A[t(a)]}6 p(a,b,c){I(a==N)H N;K d=c!=R?a.3G:[a.2G],h={"#":"1c",".":"1l"}[b.1o(0,1)]||"3h",g,i;g=h!="3h"?b.1o(1):b.5u();I((a[h]||"").1i(g)!=-1)H a;O(a=0;d&&a\'+c+""});H a}6 n(a,b){a.1e("\\n");O(K c="",d=0;d<50;d++)c+=" ";H a=v(a,6(h){I(h.1i("\\t")==-1)H h;O(K g=0;(g=h.1i("\\t"))!=-1;)h=h.1o(0,g)+c.1o(0,b-g%b)+h.1o(g+1,h.L);H h})}6 x(a){H a.Q(/^\\s+|\\s+$/g,"")}6 D(a,b){I(a.Pb.P)H 1;Y I(a.Lb.L)H 1;H 0}6 y(a,b){6 c(k){H k[0]}O(K d=N,h=[],g=b.2D?b.2D:c;(d=b.1I.X(a))!=N;){K i=g(d,b);I(1j i=="3f")i=[1f e.2L(i,d.P,b.23)];h=h.1O(i)}H h}6 E(a){K b=/(.*)((&1G;|&1y;).*)/;H a.Q(e.3A.3M,6(c){K d="",h=N;I(h=b.X(c)){c=h[1];d=h[2]}H\'\'+c+""+d})}6 z(){O(K a=1E.36("1k"),b=[],c=0;c<1z 4I="1Z://2y.3L.3K/4L/5L"><3J><4N 1Z-4M="5G-5M" 6K="2O/1z; 6J=6I-8" /><1t>6L 1v<3B 1L="25-6M:6Q,6P,6O,6N-6F;6y-2f:#6x;2f:#6w;25-22:6v;2O-3D:3C;">1v3v 3.0.76 (72 73 3x)1Z://3u.2w/1v70 17 6U 71.6T 6X-3x 6Y 6D.6t 61 60 J 1k, 5Z 5R 5V <2R/>5U 5T 5S!\'}},1Y:{2j:N,2A:{}},1U:{},3A:{6n:/\\/\\*[\\s\\S]*?\\*\\//2c,6m:/\\/\\/.*$/2c,6l:/#.*$/2c,6k:/"([^\\\\"\\n]|\\\\.)*"/g,6o:/\'([^\\\\\'\\n]|\\\\.)*\'/g,6p:1f M(\'"([^\\\\\\\\"]|\\\\\\\\.)*"\',"3z"),6s:1f M("\'([^\\\\\\\\\']|\\\\\\\\.)*\'","3z"),6q:/(&1y;|<)!--[\\s\\S]*?--(&1G;|>)/2c,3M:/\\w+:\\/\\/[\\w-.\\/?%&=:@;]*/g,6a:{18:/(&1y;|<)\\?=?/g,1b:/\\?(&1G;|>)/g},69:{18:/(&1y;|<)%=?/g,1b:/%(&1G;|>)/g},6d:{18:/(&1y;|<)\\s*1k.*?(&1G;|>)/2T,1b:/(&1y;|<)\\/\\s*1k\\s*(&1G;|>)/2T}},16:{1H:6(a){6 b(i,k){H e.16.2o(i,k,e.13.1x[k])}O(K c=\'\',d=e.16.2x,h=d.2X,g=0;g";H c},2o:6(a,b,c){H\'<2W>\'+c+""},2b:6(a){K b=a.1F,c=b.1l||"";b=B(p(b,".20",R).1c);K d=6(h){H(h=15(h+"6f(\\\\w+)").X(c))?h[1]:N}("6g");b&&d&&e.16.2x[d].2B(b);a.3N()},2x:{2X:["21","2P"],21:{1H:6(a){I(a.V("2l")!=R)H"";K b=a.V("1t");H e.16.2o(a,"21",b?b:e.13.1x.21)},2B:6(a){a=1E.6j(t(a.1c));a.1l=a.1l.Q("47","")}},2P:{2B:6(){K a="68=0";a+=", 18="+(31.30-33)/2+", 32="+(31.2Z-2Y)/2+", 30=33, 2Z=2Y";a=a.Q(/^,/,"");a=1P.6Z("","38",a);a.2C();K b=a.1E;b.6W(e.13.1x.37);b.6V();a.2C()}}}},35:6(a,b){K c;I(b)c=[b];Y{c=1E.36(e.13.34);O(K d=[],h=0;h(.*?))\\\\]$"),s=1f M("(?<27>[\\\\w-]+)\\\\s*:\\\\s*(?<1T>[\\\\w-%#]+|\\\\[.*?\\\\]|\\".*?\\"|\'.*?\')\\\\s*;?","g");(j=s.X(k))!=N;){K o=j.1T.Q(/^[\'"]|[\'"]$/g,"");I(o!=N&&m.1A(o)){o=m.X(o);o=o.2V.L>0?o.2V.1e(/\\s*,\\s*/):[]}l[j.27]=o}g={1F:g,1n:C(i,l)};g.1n.1D!=N&&d.U(g)}H d},1M:6(a,b){K c=J.35(a,b),d=N,h=e.13;I(c.L!==0)O(K g=0;g")==o-3){m=m.4h(0,o-3);s=R}l=s?m:l}I((i.1t||"")!="")k.1t=i.1t;k.1D=j;d.2Q(k);b=d.2F(l);I((i.1c||"")!="")b.1c=i.1c;i.2G.74(b,i)}}},2E:6(a){w(1P,"4k",6(){e.1M(a)})}};e.2E=e.2E;e.1M=e.1M;e.2L=6(a,b,c){J.1T=a;J.P=b;J.L=a.L;J.23=c;J.1V=N};e.2L.Z.1q=6(){H J.1T};e.4l=6(a){6 b(j,l){O(K m=0;md)1N;Y I(g.P==c.P&&g.L>c.L)a[b]=N;Y I(g.P>=c.P&&g.P\'+c+""},3Q:6(a,b){K c="",d=a.1e("\\n").L,h=2u(J.V("2i-1s")),g=J.V("2z-1s-2t");I(g==R)g=(h+d-1).1q().L;Y I(3R(g)==R)g=0;O(K i=0;i\'+j+"":"")+i)}H a},4f:6(a){H a?"<4a>"+a+"":""},4b:6(a,b){6 c(l){H(l=l?l.1V||g:g)?l+" ":""}O(K d=0,h="",g=J.V("1D",""),i=0;i|&1y;2R\\s*\\/?&1G;/2T;I(e.13.46==R)b=b.Q(h,"\\n");I(e.13.44==R)b=b.Q(h,"");b=b.1e("\\n");h=/^\\s*/;g=4Q;O(K i=0;i0;i++){K k=b[i];I(x(k).L!=0){k=h.X(k);I(k==N){a=a;1N a}g=1Q.4q(k[0].L,g)}}I(g>0)O(i=0;i\'+(J.V("16")?e.16.1H(J):"")+\'<3Z 5z="0" 5H="0" 5J="0">\'+J.4f(J.V("1t"))+"<3T><3P>"+(1u?\'<2d 1g="1u">\'+J.3Q(a)+"":"")+\'<2d 1g="17">\'+b+""},2F:6(a){I(a===N)a="";J.17=a;K b=J.3Y("T");b.3X=J.1H(a);J.V("16")&&w(p(b,".16"),"5c",e.16.2b);J.V("3V-17")&&w(p(b,".17"),"56",f);H b},2Q:6(a){J.1c=""+1Q.5d(1Q.5n()*5k).1q();e.1Y.2A[t(J.1c)]=J;J.1n=C(e.2v,a||{});I(J.V("2k")==R)J.1n.16=J.1n.1u=11},5j:6(a){a=a.Q(/^\\s+|\\s+$/g,"").Q(/\\s+/g,"|");H"\\\\b(?:"+a+")\\\\b"},5f:6(a){J.28={18:{1I:a.18,23:"1k"},1b:{1I:a.1b,23:"1k"},17:1f M("(?<18>"+a.18.1m+")(?<17>.*?)(?<1b>"+a.1b.1m+")","5o")}}};H e}();1j 2e!="1d"&&(2e.1v=1v);',62,441,'||||||function|||||||||||||||||||||||||||||||||||||return|if|this|var|length|XRegExp|null|for|index|replace|true||div|push|getParam|call|exec|else|prototype||false|lastIndex|config|arguments|RegExp|toolbar|code|left|captureNames|slice|right|id|undefined|split|new|class|addToken|indexOf|typeof|script|className|source|params|substr|apply|toString|String|line|title|gutter|SyntaxHighlighter|_xregexp|strings|lt|html|test|OUTSIDE_CLASS|match|brush|document|target|gt|getHtml|regex|global|join|style|highlight|break|concat|window|Math|isRegExp|throw|value|brushes|brushName|space|alert|vars|http|syntaxhighlighter|expandSource|size|css|case|font|Fa|name|htmlScript|dA|can|handler|gm|td|exports|color|in|href|first|discoveredBrushes|light|collapse|object|cache|getButtonHtml|trigger|pattern|getLineHtml|nbsp|numbers|parseInt|defaults|com|items|www|pad|highlighters|execute|focus|func|all|getDiv|parentNode|navigator|INSIDE_CLASS|regexList|hasFlag|Match|useScriptTags|hasNamedCapture|text|help|init|br|input|gi|Error|values|span|list|250|height|width|screen|top|500|tagName|findElements|getElementsByTagName|aboutDialog|_blank|appendChild|charAt|Array|copyAsGlobal|setFlag|highlighter_|string|attachEvent|nodeName|floor|backref|output|the|TypeError|sticky|Za|iterate|freezeTokens|scope|type|textarea|alexgorbatchev|version|margin|2010|005896|gs|regexLib|body|center|align|noBrush|require|childNodes|DTD|xhtml1|head|org|w3|url|preventDefault|container|tr|getLineNumbersHtml|isNaN|userAgent|tbody|isLineHighlighted|quick|void|innerHTML|create|table|links|auto|smart|tab|stripBrs|tabs|bloggerMode|collapsed|plain|getCodeLinesHtml|caption|getMatchesHtml|findMatches|figureOutLineNumbers|removeNestedMatches|getTitleHtml|brushNotHtmlScript|substring|createElement|Highlighter|load|HtmlScript|Brush|pre|expand|multiline|min|Can|ignoreCase|find|blur|extended|toLowerCase|aliases|addEventListener|innerText|textContent|wasn|select|createTextNode|removeChild|option|same|frame|xmlns|dtd|twice|1999|equiv|meta|htmlscript|transitional|1E3|expected|PUBLIC|DOCTYPE|on|W3C|XHTML|TR|EN|Transitional||configured|srcElement|Object|after|run|dblclick|matchChain|valueOf|constructor|default|switch|click|round|execAt|forHtmlScript|token|gimy|functions|getKeywords|1E6|escape|within|random|sgi|another|finally|supply|MSIE|ie|toUpperCase|catch|returnValue|definition|event|border|imsx|constructing|one|Infinity|from|when|Content|cellpadding|flags|cellspacing|try|xhtml|Type|spaces|2930402|hosted_button_id|lastIndexOf|donate|active|development|keep|to|xclick|_s|Xml|please|like|you|paypal|cgi|cmd|webscr|bin|highlighted|scrollbars|aspScriptTags|phpScriptTags|sort|max|scriptScriptTags|toolbar_item|_|command|command_|number|getElementById|doubleQuotedString|singleLinePerlComments|singleLineCComments|multiLineCComments|singleQuotedString|multiLineDoubleQuotedString|xmlComments|alt|multiLineSingleQuotedString|If|https|1em|000|fff|background|5em|xx|bottom|75em|Gorbatchev|large|serif|CDATA|continue|utf|charset|content|About|family|sans|Helvetica|Arial|Geneva|3em|nogutter|Copyright|syntax|close|write|2004|Alex|open|JavaScript|highlighter|July|02|replaceChild|offset|83'.split('|'),0,{})) diff --git a/scm-webapp/src/main/webapp/resources/syntaxhighlighter/scripts/shLegacy.js b/scm-webapp/src/main/webapp/resources/syntaxhighlighter/scripts/shLegacy.js new file mode 100644 index 0000000000..6d9fd4d19f --- /dev/null +++ b/scm-webapp/src/main/webapp/resources/syntaxhighlighter/scripts/shLegacy.js @@ -0,0 +1,17 @@ +/** + * SyntaxHighlighter + * http://alexgorbatchev.com/SyntaxHighlighter + * + * SyntaxHighlighter is donationware. If you are using it, please donate. + * http://alexgorbatchev.com/SyntaxHighlighter/donate.html + * + * @version + * 3.0.83 (July 02 2010) + * + * @copyright + * Copyright (C) 2004-2010 Alex Gorbatchev. + * + * @license + * Dual licensed under the MIT and GPL licenses. + */ +eval(function(p,a,c,k,e,d){e=function(c){return(c35?String.fromCharCode(c+29):c.toString(36))};if(!''.replace(/^/,String)){while(c--){d[e(c)]=k[c]||e(c)}k=[function(e){return d[e]}];e=function(){return'\\w+'};c=1};while(c--){if(k[c]){p=p.replace(new RegExp('\\b'+e(c)+'\\b','g'),k[c])}}return p}('3 u={8:{}};u.8={A:4(c,k,l,m,n,o){4 d(a,b){2 a!=1?a:b}4 f(a){2 a!=1?a.E():1}c=c.I(":");3 g=c[0],e={};t={"r":K};M=1;5=8.5;9(3 j R c)e[c[j]]="r";k=f(d(k,5.C));l=f(d(l,5.D));m=f(d(m,5.s));o=f(d(o,5.Q));n=f(d(n,5["x-y"]));2{P:g,C:d(t[e.O],k),D:d(t[e.N],l),s:d({"r":r}[e.s],m),"x-y":d(4(a,b){9(3 h=T S("^"+b+"\\\\[(?\\\\w+)\\\\]$","U"),i=1,p=0;p tags to the document body + for (i = 0; i < elements.length; i++) + { + var url = brushes[elements[i].params.brush]; + + if (!url) + continue; + + scripts[url] = false; + loadScript(url); + } + + function loadScript(url) + { + var script = document.createElement('script'), + done = false + ; + + script.src = url; + script.type = 'text/javascript'; + script.language = 'javascript'; + script.onload = script.onreadystatechange = function() + { + if (!done && (!this.readyState || this.readyState == 'loaded' || this.readyState == 'complete')) + { + done = true; + scripts[url] = true; + checkAll(); + + // Handle memory leak in IE + script.onload = script.onreadystatechange = null; + script.parentNode.removeChild(script); + } + }; + + // sync way of adding script tags to the page + document.body.appendChild(script); + }; + + function checkAll() + { + for(var url in scripts) + if (scripts[url] == false) + return; + + if (allCalled) + SyntaxHighlighter.highlight(allParams); + }; +}; + +})(); diff --git a/scm-webapp/src/main/webapp/resources/syntaxhighlighter/src/shCore.js b/scm-webapp/src/main/webapp/resources/syntaxhighlighter/src/shCore.js new file mode 100644 index 0000000000..4214763d24 --- /dev/null +++ b/scm-webapp/src/main/webapp/resources/syntaxhighlighter/src/shCore.js @@ -0,0 +1,1721 @@ +/** + * SyntaxHighlighter + * http://alexgorbatchev.com/SyntaxHighlighter + * + * SyntaxHighlighter is donationware. If you are using it, please donate. + * http://alexgorbatchev.com/SyntaxHighlighter/donate.html + * + * @version + * 3.0.83 (July 02 2010) + * + * @copyright + * Copyright (C) 2004-2010 Alex Gorbatchev. + * + * @license + * Dual licensed under the MIT and GPL licenses. + */ +// +// Begin anonymous function. This is used to contain local scope variables without polutting global scope. +// +var SyntaxHighlighter = function() { + +// CommonJS +if (typeof(require) != 'undefined' && typeof(XRegExp) == 'undefined') +{ + XRegExp = require('XRegExp').XRegExp; +} + +// Shortcut object which will be assigned to the SyntaxHighlighter variable. +// This is a shorthand for local reference in order to avoid long namespace +// references to SyntaxHighlighter.whatever... +var sh = { + defaults : { + /** Additional CSS class names to be added to highlighter elements. */ + 'class-name' : '', + + /** First line number. */ + 'first-line' : 1, + + /** + * Pads line numbers. Possible values are: + * + * false - don't pad line numbers. + * true - automaticaly pad numbers with minimum required number of leading zeroes. + * [int] - length up to which pad line numbers. + */ + 'pad-line-numbers' : false, + + /** Lines to highlight. */ + 'highlight' : null, + + /** Title to be displayed above the code block. */ + 'title' : null, + + /** Enables or disables smart tabs. */ + 'smart-tabs' : true, + + /** Gets or sets tab size. */ + 'tab-size' : 4, + + /** Enables or disables gutter. */ + 'gutter' : true, + + /** Enables or disables toolbar. */ + 'toolbar' : true, + + /** Enables quick code copy and paste from double click. */ + 'quick-code' : true, + + /** Forces code view to be collapsed. */ + 'collapse' : false, + + /** Enables or disables automatic links. */ + 'auto-links' : true, + + /** Gets or sets light mode. Equavalent to turning off gutter and toolbar. */ + 'light' : false, + + 'html-script' : false + }, + + config : { + space : ' ', + + /** Enables use of tags. */ + scriptScriptTags : { left: /(<|<)\s*script.*?(>|>)/gi, right: /(<|<)\/\s*script\s*(>|>)/gi } + }, + + toolbar: { + /** + * Generates HTML markup for the toolbar. + * @param {Highlighter} highlighter Highlighter instance. + * @return {String} Returns HTML markup. + */ + getHtml: function(highlighter) + { + var html = '
', + items = sh.toolbar.items, + list = items.list + ; + + function defaultGetHtml(highlighter, name) + { + return sh.toolbar.getButtonHtml(highlighter, name, sh.config.strings[name]); + }; + + for (var i = 0; i < list.length; i++) + html += (items[list[i]].getHtml || defaultGetHtml)(highlighter, list[i]); + + html += '
'; + + return html; + }, + + /** + * Generates HTML markup for a regular button in the toolbar. + * @param {Highlighter} highlighter Highlighter instance. + * @param {String} commandName Command name that would be executed. + * @param {String} label Label text to display. + * @return {String} Returns HTML markup. + */ + getButtonHtml: function(highlighter, commandName, label) + { + return '' + label + '' + ; + }, + + /** + * Event handler for a toolbar anchor. + */ + handler: function(e) + { + var target = e.target, + className = target.className || '' + ; + + function getValue(name) + { + var r = new RegExp(name + '_(\\w+)'), + match = r.exec(className) + ; + + return match ? match[1] : null; + }; + + var highlighter = getHighlighterById(findParentElement(target, '.syntaxhighlighter').id), + commandName = getValue('command') + ; + + // execute the toolbar command + if (highlighter && commandName) + sh.toolbar.items[commandName].execute(highlighter); + + // disable default A click behaviour + e.preventDefault(); + }, + + /** Collection of toolbar items. */ + items : { + // Ordered lis of items in the toolbar. Can't expect `for (var n in items)` to be consistent. + list: ['expandSource', 'help'], + + expandSource: { + getHtml: function(highlighter) + { + if (highlighter.getParam('collapse') != true) + return ''; + + var title = highlighter.getParam('title'); + return sh.toolbar.getButtonHtml(highlighter, 'expandSource', title ? title : sh.config.strings.expandSource); + }, + + execute: function(highlighter) + { + var div = getHighlighterDivById(highlighter.id); + removeClass(div, 'collapsed'); + } + }, + + /** Command to display the about dialog window. */ + help: { + execute: function(highlighter) + { + var wnd = popup('', '_blank', 500, 250, 'scrollbars=0'), + doc = wnd.document + ; + + doc.write(sh.config.strings.aboutDialog); + doc.close(); + wnd.focus(); + } + } + } + }, + + /** + * Finds all elements on the page which should be processes by SyntaxHighlighter. + * + * @param {Object} globalParams Optional parameters which override element's + * parameters. Only used if element is specified. + * + * @param {Object} element Optional element to highlight. If none is + * provided, all elements in the current document + * are returned which qualify. + * + * @return {Array} Returns list of { target: DOMElement, params: Object } objects. + */ + findElements: function(globalParams, element) + { + var elements = element ? [element] : toArray(document.getElementsByTagName(sh.config.tagName)), + conf = sh.config, + result = [] + ; + + // support for + + + + diff --git a/scm-webapp/src/main/webapp/resources/js/panel/sonia.panel.js b/scm-webapp/src/main/webapp/resources/js/panel/sonia.panel.js new file mode 100644 index 0000000000..4362409381 --- /dev/null +++ b/scm-webapp/src/main/webapp/resources/js/panel/sonia.panel.js @@ -0,0 +1,34 @@ +/* * + * Copyright (c) 2010, Sebastian Sdorra + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of SCM-Manager; nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 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 REGENTS 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. + * + * http://bitbucket.org/sdorra/scm-manager + * + */ + + +// register namespace +Ext.ns('Sonia.panel'); \ No newline at end of file diff --git a/scm-webapp/src/main/webapp/resources/js/panel/sonia.panel.syntaxhighlighterpanel.js b/scm-webapp/src/main/webapp/resources/js/panel/sonia.panel.syntaxhighlighterpanel.js new file mode 100644 index 0000000000..f1c3b58ae0 --- /dev/null +++ b/scm-webapp/src/main/webapp/resources/js/panel/sonia.panel.syntaxhighlighterpanel.js @@ -0,0 +1,244 @@ +/* * + * Copyright (c) 2010, Sebastian Sdorra + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of SCM-Manager; nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 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 REGENTS 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. + * + * http://bitbucket.org/sdorra/scm-manager + * + */ + + +Sonia.panel.SyntaxHighlighterPanel = Ext.extend(Ext.Panel, { + + syntaxes: [{ + name: 'ActionScript3', + aliases: ['as3', 'actionscript3'], + fileName: 'shBrushAS3.js' + },{ + name: 'Bash/shell', + aliases: ['bash', 'shell'], + fileName: 'shBrushBash.js' + },{ + name: 'ColdFusion', + aliases: ['cf', 'coldfusion'], + fileName: 'shBrushColdFusion.js' + },{ + name: 'C#', + aliases: ['c-sharp', 'csharp'], + fileName: 'shBrushCSharp.js' + },{ + name: 'C++', + aliases: ['cpp', 'c'], + fileName: 'shBrushCpp.js' + },{ + name: 'CSS', + aliases: ['css'], + fileName: 'shBrushCss.js' + },{ + name: 'Delphi', + aliases: ['delphi', 'pas', 'pascal'], + fileName: 'shBrushDelphi.js' + },{ + name: 'Diff', + aliases: ['diff', 'patch'], + fileName: 'shBrushDiff.js' + },{ + name: 'Erlang', + aliases: ['erl', 'erlang'], + fileName: 'shBrushErlang.js' + },{ + name: 'Groovy', + aliases: ['groovy'], + fileName: 'shBrushGroovy.js' + },{ + name: 'JavaScript', + aliases: ['js', 'jscript', 'javascript' ], + fileName: 'shBrushJScript.js' + },{ + name: 'Java', + aliases: ['java'], + fileName: 'shBrushJava.js' + },{ + name: 'JavaFX', + aliases: ['jfx', 'javafx'], + fileName: 'shBrushJavaFX.js' + },{ + name: 'Perl', + aliases: ['perl', 'pl'], + fileName: 'shBrushPerl.js' + },{ + name: 'PHP', + aliases: ['php'], + fileName: 'shBrushPhp.js' + },{ + name: 'Plain Text', + aliases: ['plain', 'text', 'txt'], + fileName: 'shBrushPlain.js' + },{ + name: 'PowerShell', + aliases: ['ps', 'powershell'], + fileName: 'shBrushPowerShell.js' + },{ + name: 'Python', + aliases: ['py', 'python'], + fileName: 'shBrushPython.js' + },{ + name: 'Ruby', + aliases: ['rails', 'ror', 'ruby', 'rb'], + fileName: 'shBrushRuby.js' + },{ + name: 'Scala', + aliases: ['scala'], + fileName: 'shBrushScala.js' + },{ + name: 'SQL', + aliases: ['sql'], + fileName: 'shBrushScala.js' + },{ + name: 'Visual Basic', + aliases: ['vb', 'vbnet'], + fileName: 'shBrushVb.js' + },{ + name: 'Python', + aliases: ['py', 'python'], + fileName: 'shBrushPython.js' + },{ + name: 'XML', + aliases: ['xml', 'xhtml', 'xslt', 'html', 'xhtml'], + fileName: 'shBrushXml.js' + }], + + syntax: 'plain', + brushUrl: 'shBrushPlain.js', + theme: 'Default', + shPath: 'resources/syntaxhighlighter', + contentUrl: null, + + contentLoaded: false, + scriptsLoaded: false, + + initComponent: function(){ + + if (debug){ + console.debug( 'try to find brush for ' + this.syntax ); + } + + if ( this.syntax != 'plain' ){ + var s = null; + var found = false; + for (var i=0; i' + Ext.util.Format.htmlEncode(response.responseText) + ''); + this.contentLoaded = true; + this.highlight(); + }, + failure: function(){ + // TODO + } + }); + }, + + loadBrush: function(){ + main.loadScript(this.shPath + '/scripts/' + this.brushUrl, function(){ + this.scriptsLoaded = true; + this.highlight(); + }, this); + }, + + highlight: function(){ + if (debug){ + console.debug('loaded, script: ' + this.scriptsLoaded + ", content: " + this.contentLoaded ); + } + if ( this.scriptsLoaded && this.contentLoaded ){ + if (debug){ + console.debug('call SyntaxHighlighter.highlight()'); + } + SyntaxHighlighter.highlight({}, this.body.el); + } + } + +}); + +Ext.reg('syntaxHighlighterPanel', Sonia.panel.SyntaxHighlighterPanel); \ No newline at end of file diff --git a/scm-webapp/src/main/webapp/resources/js/repository/sonia.repository.repositorybrowser.js b/scm-webapp/src/main/webapp/resources/js/repository/sonia.repository.repositorybrowser.js index 50004c86fd..2db1adf536 100644 --- a/scm-webapp/src/main/webapp/resources/js/repository/sonia.repository.repositorybrowser.js +++ b/scm-webapp/src/main/webapp/resources/js/repository/sonia.repository.repositorybrowser.js @@ -44,11 +44,6 @@ Sonia.repository.RepositoryBrowser = Ext.extend(Ext.grid.GridPanel, { initComponent: function(){ - this.syntaxes = new Array(); - this.syntaxes['java'] = 'resources/syntaxhighlighter/scripts/shBrushJava.js'; - this.syntaxes['xml'] = 'resources/syntaxhighlighter/scripts/shBrushXml.js'; - this.syntaxes['txt'] = 'resources/syntaxhighlighter/scripts/shBrushPlain.js'; - var browserStore = new Sonia.rest.JsonStore({ proxy: new Ext.data.HttpProxy({ url: restUrl + 'repositories/' + this.repository.id + '/browse.json', @@ -113,8 +108,7 @@ Sonia.repository.RepositoryBrowser = Ext.extend(Ext.grid.GridPanel, { click: { fn: this.onClick, scope: this - }, - afterRender: this.afterRender + } } }; @@ -122,14 +116,6 @@ Sonia.repository.RepositoryBrowser = Ext.extend(Ext.grid.GridPanel, { Sonia.repository.RepositoryBrowser.superclass.initComponent.apply(this, arguments); }, - afterRender: function(){ - // preload syntaxhighlighter - main.loadScript('resources/syntaxhighlighter/scripts/shCore.js'); - main.loadStylesheet('resources/syntaxhighlighter/styles/shCore.css'); - // theme onfigureable ?? - main.loadStylesheet('resources/syntaxhighlighter/styles/shCoreDefault.css'); - }, - loadStore: function(store, records, extra){ var path = extra.params.path; if ( path != null && path.length > 0 ){ @@ -201,39 +187,16 @@ Sonia.repository.RepositoryBrowser = Ext.extend(Ext.grid.GridPanel, { console.debug( 'open file: ' + path ); } - var ext = this.getExtension( path ); - var url = this.syntaxes[ext]; - if ( url == null ){ - // load plain on default - ext = "plain"; - url = this.syntaxes['txt']; - } - - main.loadScript(url); + var ext = this.getExtension( path ); main.addTab({ id: this.repository.id + "-b-" + path, - xtype: 'panel', + contentUrl: restUrl + 'repositories/' + this.repository.id + '/content?path=' + path, + xtype: 'syntaxHighlighterPanel', title: this.getName(path), closable: true, autoScroll: true, - listeners: { - afterrender: { - fn: function(panel){ - Ext.Ajax.request({ - url: restUrl + 'repositories/' + this.repository.id + '/content?path=' + path, - success: function(response){ - panel.update('
' + Ext.util.Format.htmlEncode(response.responseText) + '
'); - SyntaxHighlighter.highlight({}, panel.body.el); - }, - failure: function(){ - // TODO - } - }); - }, - scope: this - } - } + syntax: ext }); }, diff --git a/scm-webapp/src/main/webapp/resources/js/sonia.scm.js b/scm-webapp/src/main/webapp/resources/js/sonia.scm.js index ae55d966d5..80d8fa0ed4 100644 --- a/scm-webapp/src/main/webapp/resources/js/sonia.scm.js +++ b/scm-webapp/src/main/webapp/resources/js/sonia.scm.js @@ -376,13 +376,46 @@ Sonia.scm.Main = Ext.extend(Ext.util.Observable, { } }, - loadScript: function(url){ + loadScript: function(url, callback, scope){ + var doCallback = function(){ + if (debug){ + console.debug('call callback for script ' + url); + } + if ( scope ){ + callback.call(scope); + } else { + callback(); + } + } if ( this.scripts.indexOf(url) < 0 ){ var js = document.createElement('script'); js.type = "text/javascript"; js.src = url; - document.head.appendChild(js); + + if ( Ext.isIE ){ + js.onreadystatechange = function (){ + if (this.readyState === 'loaded' || + this.readyState === 'complete'){ + doCallback(); + } + } + } else { + js.onload = doCallback; + js.onerror = doCallback; + } + + if (debug){ + console.debug('load script ' + url); + } + + var head = document.getElementsByTagName('head')[0]; + head.appendChild(js); this.scripts.push(url); + } else { + if (debug){ + console.debug( 'script ' + url + ' allready loaded' ); + } + doCallback(); } }, From 3f89ee98fdd6f63bcbbf122b327486945bac3fbc Mon Sep 17 00:00:00 2001 From: Sebastian Sdorra Date: Tue, 14 Jun 2011 22:01:52 +0200 Subject: [PATCH 23/66] improve SyntaxHighlighterPanel --- .../sonia.panel.syntaxhighlighterpanel.js | 21 ++++++++----------- .../src/main/webapp/resources/js/sonia.scm.js | 6 ++++-- 2 files changed, 13 insertions(+), 14 deletions(-) diff --git a/scm-webapp/src/main/webapp/resources/js/panel/sonia.panel.syntaxhighlighterpanel.js b/scm-webapp/src/main/webapp/resources/js/panel/sonia.panel.syntaxhighlighterpanel.js index f1c3b58ae0..e25152b1fd 100644 --- a/scm-webapp/src/main/webapp/resources/js/panel/sonia.panel.syntaxhighlighterpanel.js +++ b/scm-webapp/src/main/webapp/resources/js/panel/sonia.panel.syntaxhighlighterpanel.js @@ -131,6 +131,7 @@ Sonia.panel.SyntaxHighlighterPanel = Ext.extend(Ext.Panel, { }], syntax: 'plain', + brush: 'plain', brushUrl: 'shBrushPlain.js', theme: 'Default', shPath: 'resources/syntaxhighlighter', @@ -153,7 +154,6 @@ Sonia.panel.SyntaxHighlighterPanel = Ext.extend(Ext.Panel, { for ( var j=0;j' + Ext.util.Format.htmlEncode(response.responseText) + ''); + if (debug){ + console.debug( 'load content for brush: ' + this.brush ); + } + this.update('
' + Ext.util.Format.htmlEncode(response.responseText) + '
'); this.contentLoaded = true; this.highlight(); }, diff --git a/scm-webapp/src/main/webapp/resources/js/sonia.scm.js b/scm-webapp/src/main/webapp/resources/js/sonia.scm.js index 80d8fa0ed4..a7cba94a45 100644 --- a/scm-webapp/src/main/webapp/resources/js/sonia.scm.js +++ b/scm-webapp/src/main/webapp/resources/js/sonia.scm.js @@ -390,6 +390,7 @@ Sonia.scm.Main = Ext.extend(Ext.util.Observable, { if ( this.scripts.indexOf(url) < 0 ){ var js = document.createElement('script'); js.type = "text/javascript"; + js.language = 'javascript'; js.src = url; if ( Ext.isIE ){ @@ -408,8 +409,9 @@ Sonia.scm.Main = Ext.extend(Ext.util.Observable, { console.debug('load script ' + url); } - var head = document.getElementsByTagName('head')[0]; - head.appendChild(js); + document.body.appendChild(js); + // var head = document.getElementsByTagName('head')[0]; + // head.appendChild(js); this.scripts.push(url); } else { if (debug){ From b7cfe3a14b30ceaafb8e388fa92a50ab585f7089 Mon Sep 17 00:00:00 2001 From: Sebastian Sdorra Date: Tue, 14 Jun 2011 22:11:36 +0200 Subject: [PATCH 24/66] added workaround for brush not found error --- .../resources/js/panel/sonia.panel.syntaxhighlighterpanel.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/scm-webapp/src/main/webapp/resources/js/panel/sonia.panel.syntaxhighlighterpanel.js b/scm-webapp/src/main/webapp/resources/js/panel/sonia.panel.syntaxhighlighterpanel.js index e25152b1fd..62af6545a7 100644 --- a/scm-webapp/src/main/webapp/resources/js/panel/sonia.panel.syntaxhighlighterpanel.js +++ b/scm-webapp/src/main/webapp/resources/js/panel/sonia.panel.syntaxhighlighterpanel.js @@ -233,6 +233,8 @@ Sonia.panel.SyntaxHighlighterPanel = Ext.extend(Ext.Panel, { console.debug('call SyntaxHighlighter.highlight()'); } SyntaxHighlighter.highlight({}, this.body.el); + // ugly workaround + SyntaxHighlighter.vars.discoveredBrushes = null; } } From 7f2bcacead50bc424caf63326e4e65f2ce626cb2 Mon Sep 17 00:00:00 2001 From: Sebastian Sdorra Date: Wed, 15 Jun 2011 08:56:16 +0200 Subject: [PATCH 25/66] fix bug in Sonia.util.Link --- .../sonia.repository.extendedinfopanel.js | 8 ++--- .../repository/sonia.repository.infopanel.js | 8 ++--- .../resources/js/util/sonia.util.link.js | 30 +++++++++---------- 3 files changed, 18 insertions(+), 28 deletions(-) diff --git a/scm-webapp/src/main/webapp/resources/js/repository/sonia.repository.extendedinfopanel.js b/scm-webapp/src/main/webapp/resources/js/repository/sonia.repository.extendedinfopanel.js index c558934169..af39536d8c 100644 --- a/scm-webapp/src/main/webapp/resources/js/repository/sonia.repository.extendedinfopanel.js +++ b/scm-webapp/src/main/webapp/resources/js/repository/sonia.repository.extendedinfopanel.js @@ -69,12 +69,8 @@ Sonia.repository.ExtendedInfoPanel = Ext.extend(Sonia.repository.InfoPanel,{ xtype: 'link', colspan: 2, text: this.repositoryBrowserText, - listeners: { - click: { - fn: this.openRepositoryBrowser, - scope: this - } - } + handler: this.openRepositoryBrowser, + scope: this }; }, diff --git a/scm-webapp/src/main/webapp/resources/js/repository/sonia.repository.infopanel.js b/scm-webapp/src/main/webapp/resources/js/repository/sonia.repository.infopanel.js index 997905f331..85663eb1b4 100644 --- a/scm-webapp/src/main/webapp/resources/js/repository/sonia.repository.infopanel.js +++ b/scm-webapp/src/main/webapp/resources/js/repository/sonia.repository.infopanel.js @@ -143,12 +143,8 @@ Sonia.repository.InfoPanel = Ext.extend(Ext.Panel, { xtype: 'link', colspan: 2, text: this.changesetViewerText, - listeners: { - click: { - fn: this.openChangesetViewer, - scope: this - } - } + handler: this.openChangesetViewer, + scope: this }; }, diff --git a/scm-webapp/src/main/webapp/resources/js/util/sonia.util.link.js b/scm-webapp/src/main/webapp/resources/js/util/sonia.util.link.js index cb2ce4ec08..ef1f82ac13 100644 --- a/scm-webapp/src/main/webapp/resources/js/util/sonia.util.link.js +++ b/scm-webapp/src/main/webapp/resources/js/util/sonia.util.link.js @@ -31,27 +31,25 @@ Sonia.util.Link = Ext.extend(Ext.BoxComponent, { + handler: null, + scope: null, + constructor: function(config) { config = config || {}; config.xtype = 'box'; config.autoEl = { tag: 'a', html: config.text, href: '#' }; - Sonia.util.Link.superclass.constructor.apply(this, arguments); - this.addEvents({ - 'click': true, - 'mouseover': true, - 'blur': true - }); - this.text = config.text; - }, - - onRender: function() { - theLnk = this; - this.constructor.superclass.onRender.apply(this, arguments); - if (!theLnk.disabled) { - this.el.on('blur', function(e) { theLnk.fireEvent('blur'); }); - this.el.on('click', function(e) { theLnk.fireEvent('click'); }); - this.el.on('mouseover', function(e) { theLnk.fireEvent('mouseover'); }); + config.listeners = { + render: function(c) { + c.getEl().on('click', function(){ + if (this.handler){ + this.scope ? this.handler.call(this.scope) : this.handler(); + } + }, this); + } } + + Sonia.util.Link.superclass.constructor.apply(this, arguments); + this.text = config.text; } }); From 1f09fb4956134cab9182ce892cb1bb9741e137e0 Mon Sep 17 00:00:00 2001 From: Sebastian Sdorra Date: Wed, 15 Jun 2011 15:14:48 +0200 Subject: [PATCH 26/66] fix missing scrollbars --- .../js/repository/sonia.repository.repositorybrowser.js | 1 - 1 file changed, 1 deletion(-) diff --git a/scm-webapp/src/main/webapp/resources/js/repository/sonia.repository.repositorybrowser.js b/scm-webapp/src/main/webapp/resources/js/repository/sonia.repository.repositorybrowser.js index 2db1adf536..a9d7f7ad79 100644 --- a/scm-webapp/src/main/webapp/resources/js/repository/sonia.repository.repositorybrowser.js +++ b/scm-webapp/src/main/webapp/resources/js/repository/sonia.repository.repositorybrowser.js @@ -98,7 +98,6 @@ Sonia.repository.RepositoryBrowser = Ext.extend(Ext.grid.GridPanel, { }); var config = { - autoHeight: true, autoExpandColumn: 'description', title: String.format(this.repositoryBrowserTitleText, this.repository.name), store: browserStore, From 8facd889c89c5c315cfbd5531a1df945b29d2f56 Mon Sep 17 00:00:00 2001 From: Sebastian Sdorra Date: Wed, 15 Jun 2011 15:17:32 +0200 Subject: [PATCH 27/66] remove unused field --- .../js/repository/sonia.repository.repositorybrowser.js | 2 -- 1 file changed, 2 deletions(-) diff --git a/scm-webapp/src/main/webapp/resources/js/repository/sonia.repository.repositorybrowser.js b/scm-webapp/src/main/webapp/resources/js/repository/sonia.repository.repositorybrowser.js index a9d7f7ad79..e44c0ebb61 100644 --- a/scm-webapp/src/main/webapp/resources/js/repository/sonia.repository.repositorybrowser.js +++ b/scm-webapp/src/main/webapp/resources/js/repository/sonia.repository.repositorybrowser.js @@ -39,8 +39,6 @@ Sonia.repository.RepositoryBrowser = Ext.extend(Ext.grid.GridPanel, { iconDocument: 'resources/images/document.gif', templateIcon: '{1}', templateLink: '{0}', - - syntaxes: null, initComponent: function(){ From bf5fad9c8469520520526015845646926631a635 Mon Sep 17 00:00:00 2001 From: Sebastian Sdorra Date: Wed, 15 Jun 2011 15:31:25 +0200 Subject: [PATCH 28/66] added support for different revisions to Sonia.repository.RepositoryBrowser --- .../sonia.repository.repositorybrowser.js | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/scm-webapp/src/main/webapp/resources/js/repository/sonia.repository.repositorybrowser.js b/scm-webapp/src/main/webapp/resources/js/repository/sonia.repository.repositorybrowser.js index e44c0ebb61..6801eab991 100644 --- a/scm-webapp/src/main/webapp/resources/js/repository/sonia.repository.repositorybrowser.js +++ b/scm-webapp/src/main/webapp/resources/js/repository/sonia.repository.repositorybrowser.js @@ -32,6 +32,7 @@ Sonia.repository.RepositoryBrowser = Ext.extend(Ext.grid.GridPanel, { repository: null, + revision: null, // TODO i18n repositoryBrowserTitleText: 'RepositoryBrowser: {0}', @@ -60,6 +61,12 @@ Sonia.repository.RepositoryBrowser = Ext.extend(Ext.grid.GridPanel, { } }); + if ( this.revision ){ + browserStore.baseParams = { + revision: this.revision + }; + } + var browserColModel = new Ext.grid.ColumnModel({ defaults: { sortable: false @@ -186,9 +193,14 @@ Sonia.repository.RepositoryBrowser = Ext.extend(Ext.grid.GridPanel, { var ext = this.getExtension( path ); + var url = restUrl + 'repositories/' + this.repository.id + '/content?path=' + path; + if ( this.revision ){ + url += "&revision=" + this.revision; + } + main.addTab({ id: this.repository.id + "-b-" + path, - contentUrl: restUrl + 'repositories/' + this.repository.id + '/content?path=' + path, + contentUrl: url, xtype: 'syntaxHighlighterPanel', title: this.getName(path), closable: true, From bd8c53f85e4969daa031493574762418cfcc61b4 Mon Sep 17 00:00:00 2001 From: Sebastian Sdorra Date: Wed, 15 Jun 2011 15:55:25 +0200 Subject: [PATCH 29/66] create link from changesetviewer to repositorybrowser --- scm-webapp/pom.xml | 2 +- .../sonia.repository.changesetviewergrid.js | 39 ++++++++++++++++++- .../sonia.repository.repositorybrowser.js | 4 ++ 3 files changed, 42 insertions(+), 3 deletions(-) diff --git a/scm-webapp/pom.xml b/scm-webapp/pom.xml index e88ad2a3f3..81c529e6ba 100644 --- a/scm-webapp/pom.xml +++ b/scm-webapp/pom.xml @@ -305,7 +305,7 @@ 1.11 1.0-beta-7 3.0.3 - Tomcat70 + gfv3ee6 diff --git a/scm-webapp/src/main/webapp/resources/js/repository/sonia.repository.changesetviewergrid.js b/scm-webapp/src/main/webapp/resources/js/repository/sonia.repository.changesetviewergrid.js index ebf4369512..71ccc5d4d5 100644 --- a/scm-webapp/src/main/webapp/resources/js/repository/sonia.repository.changesetviewergrid.js +++ b/scm-webapp/src/main/webapp/resources/js/repository/sonia.repository.changesetviewergrid.js @@ -44,7 +44,8 @@ Sonia.repository.ChangesetViewerGrid = Ext.extend(Ext.grid.GridPanel, { Modified{1}\ Deleted{2}\ ', - idsTemplate: 'Commit: {0}', + idsTemplate: '
Commit: {0}
\ +
Tree: {0}
', tagsAndBranchesTemplate: '
{0}
\
{1}
', @@ -86,13 +87,47 @@ Sonia.repository.ChangesetViewerGrid = Ext.extend(Ext.grid.GridPanel, { autoHeight: true, hideHeaders: true, colModel: changesetColModel, - loadMask: true + loadMask: true, + listeners: { + click: { + fn: this.onClick, + scope: this + } + } } Ext.apply(this, Ext.apply(this.initialConfig, config)); Sonia.repository.ChangesetViewerGrid.superclass.initComponent.apply(this, arguments); }, + onClick: function(e){ + var el = e.getTarget('.cs-tree-link'); + + if ( el != null ){ + var revision = el.rel; + var index = revision.indexOf(':'); + if ( index >= 0 ){ + revision = revision.substr(index+1); + } + + if (debug){ + console.debug('load repositorybrowser for ' + revision); + } + + this.openRepositoryBrowser(revision); + } + }, + + openRepositoryBrowser: function(revision){ + main.addTab({ + id: 'repositorybrowser-' + this.repository.id + '-' + revision, + xtype: 'repositoryBrowser', + repository: this.repository, + revision: revision, + closable: true + }); + }, + renderChangesetMetadata: function(author, p, record){ var authorValue = ''; if ( author != null ){ diff --git a/scm-webapp/src/main/webapp/resources/js/repository/sonia.repository.repositorybrowser.js b/scm-webapp/src/main/webapp/resources/js/repository/sonia.repository.repositorybrowser.js index 6801eab991..d4dd7a0422 100644 --- a/scm-webapp/src/main/webapp/resources/js/repository/sonia.repository.repositorybrowser.js +++ b/scm-webapp/src/main/webapp/resources/js/repository/sonia.repository.repositorybrowser.js @@ -43,6 +43,10 @@ Sonia.repository.RepositoryBrowser = Ext.extend(Ext.grid.GridPanel, { initComponent: function(){ + if (debug){ + console.debug('create new browser for repository ' + this.repository.name + " and revision " + this.revision); + } + var browserStore = new Sonia.rest.JsonStore({ proxy: new Ext.data.HttpProxy({ url: restUrl + 'repositories/' + this.repository.id + '/browse.json', From 89d790da440c1289b3d12457310f39eaef3278ac Mon Sep 17 00:00:00 2001 From: Sebastian Sdorra Date: Wed, 15 Jun 2011 16:57:09 +0200 Subject: [PATCH 30/66] start implementing SvnRepositoryBrowser --- .../scm/repository/SvnRepositoryBrowser.java | 224 ++++++++++++++++++ .../scm/repository/SvnRepositoryHandler.java | 20 ++ 2 files changed, 244 insertions(+) create mode 100644 plugins/scm-svn-plugin/src/main/java/sonia/scm/repository/SvnRepositoryBrowser.java diff --git a/plugins/scm-svn-plugin/src/main/java/sonia/scm/repository/SvnRepositoryBrowser.java b/plugins/scm-svn-plugin/src/main/java/sonia/scm/repository/SvnRepositoryBrowser.java new file mode 100644 index 0000000000..486822761c --- /dev/null +++ b/plugins/scm-svn-plugin/src/main/java/sonia/scm/repository/SvnRepositoryBrowser.java @@ -0,0 +1,224 @@ +/** + * Copyright (c) 2010, Sebastian Sdorra + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of SCM-Manager; nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 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 REGENTS 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. + * + * http://bitbucket.org/sdorra/scm-manager + * + */ + + + +package sonia.scm.repository; + +//~--- non-JDK imports -------------------------------------------------------- + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import org.tmatesoft.svn.core.SVNDirEntry; +import org.tmatesoft.svn.core.SVNException; +import org.tmatesoft.svn.core.SVNNodeKind; +import org.tmatesoft.svn.core.SVNURL; +import org.tmatesoft.svn.core.io.SVNRepository; +import org.tmatesoft.svn.core.io.SVNRepositoryFactory; + +import sonia.scm.util.Util; + +//~--- JDK imports ------------------------------------------------------------ + +import java.io.File; +import java.io.IOException; +import java.io.InputStream; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; + +/** + * + * @author Sebastian Sdorra + */ +public class SvnRepositoryBrowser implements RepositoryBrowser +{ + + /** the logger for SvnRepositoryBrowser */ + private static final Logger logger = + LoggerFactory.getLogger(SvnRepositoryBrowser.class); + + //~--- constructors --------------------------------------------------------- + + /** + * Constructs ... + * + * + * @param handler + * @param repository + */ + public SvnRepositoryBrowser(SvnRepositoryHandler handler, + Repository repository) + { + this.handler = handler; + this.repository = repository; + } + + //~--- get methods ---------------------------------------------------------- + + /** + * Method description + * + * + * @param revision + * @param path + * + * @return + * + * @throws IOException + * @throws RepositoryException + */ + @Override + public InputStream getContent(String revision, String path) + throws IOException, RepositoryException + { + + // http://wiki.svnkit.com/Printing_Out_File_Contents + throw new UnsupportedOperationException("Not supported yet."); + } + + /** + * Method description + * + * + * @param revision + * @param path + * + * @return + * + * @throws IOException + * @throws RepositoryException + */ + @Override + public BrowserResult getResult(String revision, String path) + throws IOException, RepositoryException + { + long revisionNumber = -1; + + if (Util.isNotEmpty(revision)) + { + try + { + revisionNumber = Long.parseLong(revision); + } + catch (NumberFormatException ex) + { + throw new RepositoryException("given revision is not a svnrevision"); + } + } + + if (logger.isDebugEnabled()) + { + logger.debug("browser repository {} in path {} at revision {}", + new Object[] { repository.getName(), + path, revision }); + } + + File directory = handler.getDirectory(repository); + BrowserResult result = null; + SVNRepository svnRepository = null; + + try + { + svnRepository = SVNRepositoryFactory.create(SVNURL.fromFile(directory)); + + Collection entries = + svnRepository.getDir(Util.nonNull(path), revisionNumber, null, + (Collection) null); + List children = new ArrayList(); + + for (SVNDirEntry entry : entries) + { + children.add(createFileObject(entry)); + } + + result = new BrowserResult(); + result.setRevision(revision); + + // TODO create full root file + FileObject dir = new FileObject(); + + dir.setDirectory(true); + dir.setChildren(children); + dir.setPath(path); + result.setFile(dir); + } + catch (SVNException ex) + { + logger.error("could not open repository", ex); + } + finally + { + svnRepository.closeSession(); + } + + return result; + } + + //~--- methods -------------------------------------------------------------- + + /** + * Method description + * + * + * @param entry + * + * @return + */ + private FileObject createFileObject(SVNDirEntry entry) + { + FileObject fileObject = new FileObject(); + + fileObject.setName(entry.getName()); + fileObject.setPath(entry.getRelativePath()); + fileObject.setDirectory(entry.getKind() == SVNNodeKind.DIR); + + if (entry.getDate() != null) + { + fileObject.setLastModified(entry.getDate().getTime()); + } + + fileObject.setLength(entry.getSize()); + fileObject.setDescription(entry.getCommitMessage()); + + return fileObject; + } + + //~--- fields --------------------------------------------------------------- + + /** Field description */ + private SvnRepositoryHandler handler; + + /** Field description */ + private Repository repository; +} diff --git a/plugins/scm-svn-plugin/src/main/java/sonia/scm/repository/SvnRepositoryHandler.java b/plugins/scm-svn-plugin/src/main/java/sonia/scm/repository/SvnRepositoryHandler.java index 182a0b951b..2cccb9347b 100644 --- a/plugins/scm-svn-plugin/src/main/java/sonia/scm/repository/SvnRepositoryHandler.java +++ b/plugins/scm-svn-plugin/src/main/java/sonia/scm/repository/SvnRepositoryHandler.java @@ -42,6 +42,7 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.tmatesoft.svn.core.SVNException; +import org.tmatesoft.svn.core.internal.io.fs.FSRepositoryFactory; import org.tmatesoft.svn.core.io.SVNRepositoryFactory; import sonia.scm.Type; @@ -91,6 +92,9 @@ public class SvnRepositoryHandler public SvnRepositoryHandler(StoreFactory storeFactory, FileSystem fileSystem) { super(storeFactory, fileSystem); + + // setup FSRepositoryFactory for SvnRepositoryBrowser + FSRepositoryFactory.setup(); } //~--- get methods ---------------------------------------------------------- @@ -126,6 +130,22 @@ public class SvnRepositoryHandler return changesetViewer; } + /** + * Method description + * + * + * @param repository + * + * @return + */ + @Override + public RepositoryBrowser getRepositoryBrowser(Repository repository) + { + AssertUtil.assertIsNotNull(repository); + + return new SvnRepositoryBrowser(this, repository); + } + /** * Method description * From 6049aea754dbc34649f59fb837e79026d06c4159 Mon Sep 17 00:00:00 2001 From: Sebastian Sdorra Date: Thu, 16 Jun 2011 16:46:14 +0200 Subject: [PATCH 31/66] fix change directory in svn repositorybrowser --- .../scm/repository/SvnRepositoryBrowser.java | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/plugins/scm-svn-plugin/src/main/java/sonia/scm/repository/SvnRepositoryBrowser.java b/plugins/scm-svn-plugin/src/main/java/sonia/scm/repository/SvnRepositoryBrowser.java index 486822761c..ef27d18713 100644 --- a/plugins/scm-svn-plugin/src/main/java/sonia/scm/repository/SvnRepositoryBrowser.java +++ b/plugins/scm-svn-plugin/src/main/java/sonia/scm/repository/SvnRepositoryBrowser.java @@ -156,10 +156,21 @@ public class SvnRepositoryBrowser implements RepositoryBrowser svnRepository.getDir(Util.nonNull(path), revisionNumber, null, (Collection) null); List children = new ArrayList(); + String basePath = Util.EMPTY_STRING; + + if (Util.isNotEmpty(path)) + { + basePath = path; + + if (!basePath.endsWith("/")) + { + basePath = basePath.concat("/"); + } + } for (SVNDirEntry entry : entries) { - children.add(createFileObject(entry)); + children.add(createFileObject(entry, basePath)); } result = new BrowserResult(); @@ -192,15 +203,16 @@ public class SvnRepositoryBrowser implements RepositoryBrowser * * * @param entry + * @param path * * @return */ - private FileObject createFileObject(SVNDirEntry entry) + private FileObject createFileObject(SVNDirEntry entry, String path) { FileObject fileObject = new FileObject(); fileObject.setName(entry.getName()); - fileObject.setPath(entry.getRelativePath()); + fileObject.setPath(path.concat(entry.getRelativePath())); fileObject.setDirectory(entry.getKind() == SVNNodeKind.DIR); if (entry.getDate() != null) From dda56fb7502548f507a279efffb838f3fd499c38 Mon Sep 17 00:00:00 2001 From: Sebastian Sdorra Date: Thu, 16 Jun 2011 16:58:20 +0200 Subject: [PATCH 32/66] implement svn getContent for the repositorybrowser --- .../scm/repository/SvnRepositoryBrowser.java | 94 +++++++++++++++---- 1 file changed, 76 insertions(+), 18 deletions(-) diff --git a/plugins/scm-svn-plugin/src/main/java/sonia/scm/repository/SvnRepositoryBrowser.java b/plugins/scm-svn-plugin/src/main/java/sonia/scm/repository/SvnRepositoryBrowser.java index ef27d18713..eef15c2767 100644 --- a/plugins/scm-svn-plugin/src/main/java/sonia/scm/repository/SvnRepositoryBrowser.java +++ b/plugins/scm-svn-plugin/src/main/java/sonia/scm/repository/SvnRepositoryBrowser.java @@ -41,6 +41,7 @@ import org.slf4j.LoggerFactory; import org.tmatesoft.svn.core.SVNDirEntry; import org.tmatesoft.svn.core.SVNException; import org.tmatesoft.svn.core.SVNNodeKind; +import org.tmatesoft.svn.core.SVNProperties; import org.tmatesoft.svn.core.SVNURL; import org.tmatesoft.svn.core.io.SVNRepository; import org.tmatesoft.svn.core.io.SVNRepositoryFactory; @@ -49,6 +50,8 @@ import sonia.scm.util.Util; //~--- JDK imports ------------------------------------------------------------ +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; import java.io.File; import java.io.IOException; import java.io.InputStream; @@ -87,7 +90,7 @@ public class SvnRepositoryBrowser implements RepositoryBrowser //~--- get methods ---------------------------------------------------------- /** - * Method description + * http://wiki.svnkit.com/Printing_Out_File_Contents * * * @param revision @@ -103,8 +106,30 @@ public class SvnRepositoryBrowser implements RepositoryBrowser throws IOException, RepositoryException { - // http://wiki.svnkit.com/Printing_Out_File_Contents - throw new UnsupportedOperationException("Not supported yet."); + // TODO change the api, to remove the ByteArray streams + InputStream content = null; + long revisionNumber = getRevisionNumber(revision); + SVNRepository svnRepository = null; + + try + { + svnRepository = getSvnRepository(); + + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + + svnRepository.getFile(path, revisionNumber, new SVNProperties(), baos); + content = new ByteArrayInputStream(baos.toByteArray()); + } + catch (SVNException ex) + { + logger.error("could not open repository", ex); + } + finally + { + svnRepository.closeSession(); + } + + return content; } /** @@ -123,19 +148,7 @@ public class SvnRepositoryBrowser implements RepositoryBrowser public BrowserResult getResult(String revision, String path) throws IOException, RepositoryException { - long revisionNumber = -1; - - if (Util.isNotEmpty(revision)) - { - try - { - revisionNumber = Long.parseLong(revision); - } - catch (NumberFormatException ex) - { - throw new RepositoryException("given revision is not a svnrevision"); - } - } + long revisionNumber = getRevisionNumber(revision); if (logger.isDebugEnabled()) { @@ -144,13 +157,12 @@ public class SvnRepositoryBrowser implements RepositoryBrowser path, revision }); } - File directory = handler.getDirectory(repository); BrowserResult result = null; SVNRepository svnRepository = null; try { - svnRepository = SVNRepositoryFactory.create(SVNURL.fromFile(directory)); + svnRepository = getSvnRepository(); Collection entries = svnRepository.getDir(Util.nonNull(path), revisionNumber, null, @@ -226,6 +238,52 @@ public class SvnRepositoryBrowser implements RepositoryBrowser return fileObject; } + //~--- get methods ---------------------------------------------------------- + + /** + * Method description + * + * + * @param revision + * + * @return + * + * @throws RepositoryException + */ + private long getRevisionNumber(String revision) throws RepositoryException + { + long revisionNumber = -1; + + if (Util.isNotEmpty(revision)) + { + try + { + revisionNumber = Long.parseLong(revision); + } + catch (NumberFormatException ex) + { + throw new RepositoryException("given revision is not a svnrevision"); + } + } + + return revisionNumber; + } + + /** + * Method description + * + * + * @return + * + * @throws SVNException + */ + private SVNRepository getSvnRepository() throws SVNException + { + File directory = handler.getDirectory(repository); + + return SVNRepositoryFactory.create(SVNURL.fromFile(directory)); + } + //~--- fields --------------------------------------------------------------- /** Field description */ From 5f426f3e132c44edb2d5f018986118bb519d5743 Mon Sep 17 00:00:00 2001 From: Sebastian Sdorra Date: Fri, 17 Jun 2011 12:53:47 +0200 Subject: [PATCH 33/66] start implementation of git repositorybrowser --- .../scm/repository/GitRepositoryBrowser.java | 219 ++++++++++++++++++ .../scm/repository/GitRepositoryHandler.java | 16 ++ 2 files changed, 235 insertions(+) create mode 100644 plugins/scm-git-plugin/src/main/java/sonia/scm/repository/GitRepositoryBrowser.java diff --git a/plugins/scm-git-plugin/src/main/java/sonia/scm/repository/GitRepositoryBrowser.java b/plugins/scm-git-plugin/src/main/java/sonia/scm/repository/GitRepositoryBrowser.java new file mode 100644 index 0000000000..bfde6aaf2c --- /dev/null +++ b/plugins/scm-git-plugin/src/main/java/sonia/scm/repository/GitRepositoryBrowser.java @@ -0,0 +1,219 @@ +/** + * Copyright (c) 2010, Sebastian Sdorra + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of SCM-Manager; nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 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 REGENTS 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. + * + * http://bitbucket.org/sdorra/scm-manager + * + */ + + + +package sonia.scm.repository; + +//~--- non-JDK imports -------------------------------------------------------- + +import org.eclipse.jgit.dircache.DirCache; +import org.eclipse.jgit.dircache.DirCacheIterator; +import org.eclipse.jgit.errors.MissingObjectException; +import org.eclipse.jgit.lib.Constants; +import org.eclipse.jgit.lib.ObjectId; +import org.eclipse.jgit.lib.ObjectLoader; +import org.eclipse.jgit.lib.RepositoryCache; +import org.eclipse.jgit.revwalk.RevWalk; +import org.eclipse.jgit.treewalk.TreeWalk; +import org.eclipse.jgit.util.FS; + +import sonia.scm.util.Util; + +//~--- JDK imports ------------------------------------------------------------ + +import java.io.File; +import java.io.IOException; +import java.io.InputStream; + +import java.util.ArrayList; +import java.util.List; + +/** + * + * @author Sebastian Sdorra + */ +public class GitRepositoryBrowser implements RepositoryBrowser +{ + + /** + * Constructs ... + * + * + * @param handler + * @param repository + */ + public GitRepositoryBrowser(GitRepositoryHandler handler, + Repository repository) + { + this.handler = handler; + this.repository = repository; + } + + //~--- get methods ---------------------------------------------------------- + + /** + * Method description + * + * + * @param revision + * @param path + * + * @return + * + * @throws IOException + * @throws RepositoryException + */ + @Override + public InputStream getContent(String revision, String path) + throws IOException, RepositoryException + { + throw new UnsupportedOperationException("Not supported yet."); + } + + /** + * Method description + * + * + * @param revision + * @param path + * + * @return + * + * @throws IOException + * @throws RepositoryException + */ + @Override + public BrowserResult getResult(String revision, String path) + throws IOException, RepositoryException + { + BrowserResult result = null; + File directory = handler.getDirectory(repository); + org.eclipse.jgit.lib.Repository repo = + RepositoryCache.open(RepositoryCache.FileKey.lenient(directory, + FS.DETECTED), true); + + try + { + + ObjectId revId = getRevisionId(repo, revision); + + DirCache cache = new DirCache(directory, FS.DETECTED); + TreeWalk treeWalk = new TreeWalk(repo); + + treeWalk.addTree(new RevWalk(repo).parseTree(revId)); + treeWalk.addTree(new DirCacheIterator(cache)); + result = new BrowserResult(); + + FileObject root = new FileObject(); + + root.setDirectory(true); + root.setPath(Util.nonNull(path)); + + List files = new ArrayList(); + + root.setChildren(files); + result.setFile(root); + result.setRevision(revId.getName()); + + while (treeWalk.next()) + { + files.add(createFileObject(repo, treeWalk)); + } + } + finally + { + if (repo != null) + { + repo.close(); + } + } + + return result; + } + + + private ObjectId getRevisionId( org.eclipse.jgit.lib.Repository repo, String revision ) throws IOException{ + ObjectId revId = null; + + if (Util.isNotEmpty(revision)) + { + revId = repo.resolve(revision); + } + else + { + revId = repo.resolve(Constants.HEAD); + } + return revId; + } + + //~--- methods -------------------------------------------------------------- + + /** + * Method description + * + * + * @param repo + * @param treeWalk + * + * @return + * + * @throws IOException + * @throws MissingObjectException + */ + private FileObject createFileObject(org.eclipse.jgit.lib.Repository repo, + TreeWalk treeWalk) + throws IOException + { + FileObject file = new FileObject(); + + file.setName(treeWalk.getNameString()); + file.setPath(treeWalk.getPathString()); + + ObjectLoader loader = repo.open(treeWalk.getObjectId(0)); + + file.setDirectory(loader.getType() == Constants.OBJ_TREE); + file.setLength(loader.getSize()); + + // TODO + file.setLastModified(System.currentTimeMillis()); + + return file; + } + + //~--- fields --------------------------------------------------------------- + + /** Field description */ + private GitRepositoryHandler handler; + + /** Field description */ + private Repository repository; +} diff --git a/plugins/scm-git-plugin/src/main/java/sonia/scm/repository/GitRepositoryHandler.java b/plugins/scm-git-plugin/src/main/java/sonia/scm/repository/GitRepositoryHandler.java index f414446076..0b2dfa2b55 100644 --- a/plugins/scm-git-plugin/src/main/java/sonia/scm/repository/GitRepositoryHandler.java +++ b/plugins/scm-git-plugin/src/main/java/sonia/scm/repository/GitRepositoryHandler.java @@ -119,6 +119,22 @@ public class GitRepositoryHandler return changesetViewer; } + /** + * Method description + * + * + * @param repository + * + * @return + */ + @Override + public RepositoryBrowser getRepositoryBrowser(Repository repository) + { + AssertUtil.assertIsNotNull(repository); + + return new GitRepositoryBrowser(this, repository); + } + /** * Method description * From 7d758aed6c3288268936c7de39a7fa69987d6c6b Mon Sep 17 00:00:00 2001 From: Sebastian Sdorra Date: Sat, 18 Jun 2011 16:26:23 +0200 Subject: [PATCH 34/66] added not found repository exceptions --- .../scm/repository/PathNotFoundException.java | 81 +++++++++++++++++++ .../repository/RevisionNotFoundException.java | 81 +++++++++++++++++++ 2 files changed, 162 insertions(+) create mode 100644 scm-core/src/main/java/sonia/scm/repository/PathNotFoundException.java create mode 100644 scm-core/src/main/java/sonia/scm/repository/RevisionNotFoundException.java diff --git a/scm-core/src/main/java/sonia/scm/repository/PathNotFoundException.java b/scm-core/src/main/java/sonia/scm/repository/PathNotFoundException.java new file mode 100644 index 0000000000..6454fa265c --- /dev/null +++ b/scm-core/src/main/java/sonia/scm/repository/PathNotFoundException.java @@ -0,0 +1,81 @@ +/** + * Copyright (c) 2010, Sebastian Sdorra + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of SCM-Manager; nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 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 REGENTS 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. + * + * http://bitbucket.org/sdorra/scm-manager + * + */ + + + +package sonia.scm.repository; + +//~--- non-JDK imports -------------------------------------------------------- + +import sonia.scm.util.Util; + +/** + * + * @author Sebastian Sdorra + */ +public class PathNotFoundException extends RepositoryException +{ + + /** Field description */ + private static final long serialVersionUID = 4629690181172951809L; + + //~--- constructors --------------------------------------------------------- + + /** + * Constructs ... + * + * + * @param path + */ + public PathNotFoundException(String path) + { + super("path \"".concat(Util.nonNull(path)).concat("\" not found")); + this.path = Util.nonNull(path); + } + + //~--- get methods ---------------------------------------------------------- + + /** + * Method description + * + * + * @return + */ + public String getPath() + { + return path; + } + + //~--- fields --------------------------------------------------------------- + + /** Field description */ + private String path; +} diff --git a/scm-core/src/main/java/sonia/scm/repository/RevisionNotFoundException.java b/scm-core/src/main/java/sonia/scm/repository/RevisionNotFoundException.java new file mode 100644 index 0000000000..e9f2c95fe1 --- /dev/null +++ b/scm-core/src/main/java/sonia/scm/repository/RevisionNotFoundException.java @@ -0,0 +1,81 @@ +/** + * Copyright (c) 2010, Sebastian Sdorra + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of SCM-Manager; nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 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 REGENTS 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. + * + * http://bitbucket.org/sdorra/scm-manager + * + */ + + + +package sonia.scm.repository; + +//~--- non-JDK imports -------------------------------------------------------- + +import sonia.scm.util.Util; + +/** + * + * @author Sebastian Sdorra + */ +public class RevisionNotFoundException extends RepositoryException +{ + + /** Field description */ + private static final long serialVersionUID = -5594008535358811998L; + + //~--- constructors --------------------------------------------------------- + + /** + * Constructs ... + * + * + * @param revision + */ + public RevisionNotFoundException(String revision) + { + super("revision \"".concat(Util.nonNull(revision)).concat("\" not found")); + this.revision = Util.nonNull(revision); + } + + //~--- get methods ---------------------------------------------------------- + + /** + * Method description + * + * + * @return + */ + public String getRevision() + { + return revision; + } + + //~--- fields --------------------------------------------------------------- + + /** Field description */ + private String revision; +} From 5adea3f28bf8b717ab601ca2e8380a027f47fde4 Mon Sep 17 00:00:00 2001 From: Sebastian Sdorra Date: Sat, 18 Jun 2011 16:41:23 +0200 Subject: [PATCH 35/66] improve repository browser api --- .../scm/repository/GitRepositoryBrowser.java | 56 +++++---- .../scm/repository/HgRepositoryBrowser.java | 17 ++- .../scm/repository/SvnRepositoryBrowser.java | 37 +++--- .../scm/repository/RepositoryBrowser.java | 6 +- .../rest/resources/RepositoryResource.java | 108 +++++++++++++----- 5 files changed, 149 insertions(+), 75 deletions(-) diff --git a/plugins/scm-git-plugin/src/main/java/sonia/scm/repository/GitRepositoryBrowser.java b/plugins/scm-git-plugin/src/main/java/sonia/scm/repository/GitRepositoryBrowser.java index bfde6aaf2c..a56405df0e 100644 --- a/plugins/scm-git-plugin/src/main/java/sonia/scm/repository/GitRepositoryBrowser.java +++ b/plugins/scm-git-plugin/src/main/java/sonia/scm/repository/GitRepositoryBrowser.java @@ -37,7 +37,6 @@ package sonia.scm.repository; import org.eclipse.jgit.dircache.DirCache; import org.eclipse.jgit.dircache.DirCacheIterator; -import org.eclipse.jgit.errors.MissingObjectException; import org.eclipse.jgit.lib.Constants; import org.eclipse.jgit.lib.ObjectId; import org.eclipse.jgit.lib.ObjectLoader; @@ -52,7 +51,7 @@ import sonia.scm.util.Util; import java.io.File; import java.io.IOException; -import java.io.InputStream; +import java.io.OutputStream; import java.util.ArrayList; import java.util.List; @@ -86,14 +85,14 @@ public class GitRepositoryBrowser implements RepositoryBrowser * * @param revision * @param path + * @param output * - * @return * * @throws IOException * @throws RepositoryException */ @Override - public InputStream getContent(String revision, String path) + public void getContent(String revision, String path, OutputStream output) throws IOException, RepositoryException { throw new UnsupportedOperationException("Not supported yet."); @@ -123,9 +122,7 @@ public class GitRepositoryBrowser implements RepositoryBrowser try { - ObjectId revId = getRevisionId(repo, revision); - DirCache cache = new DirCache(directory, FS.DETECTED); TreeWalk treeWalk = new TreeWalk(repo); @@ -159,21 +156,6 @@ public class GitRepositoryBrowser implements RepositoryBrowser return result; } - - - private ObjectId getRevisionId( org.eclipse.jgit.lib.Repository repo, String revision ) throws IOException{ - ObjectId revId = null; - - if (Util.isNotEmpty(revision)) - { - revId = repo.resolve(revision); - } - else - { - revId = repo.resolve(Constants.HEAD); - } - return revId; - } //~--- methods -------------------------------------------------------------- @@ -187,7 +169,6 @@ public class GitRepositoryBrowser implements RepositoryBrowser * @return * * @throws IOException - * @throws MissingObjectException */ private FileObject createFileObject(org.eclipse.jgit.lib.Repository repo, TreeWalk treeWalk) @@ -209,6 +190,37 @@ public class GitRepositoryBrowser implements RepositoryBrowser return file; } + //~--- get methods ---------------------------------------------------------- + + /** + * Method description + * + * + * @param repo + * @param revision + * + * @return + * + * @throws IOException + */ + private ObjectId getRevisionId(org.eclipse.jgit.lib.Repository repo, + String revision) + throws IOException + { + ObjectId revId = null; + + if (Util.isNotEmpty(revision)) + { + revId = repo.resolve(revision); + } + else + { + revId = repo.resolve(Constants.HEAD); + } + + return revId; + } + //~--- fields --------------------------------------------------------------- /** Field description */ diff --git a/plugins/scm-hg-plugin/src/main/java/sonia/scm/repository/HgRepositoryBrowser.java b/plugins/scm-hg-plugin/src/main/java/sonia/scm/repository/HgRepositoryBrowser.java index 342d25da5a..838f23c03a 100644 --- a/plugins/scm-hg-plugin/src/main/java/sonia/scm/repository/HgRepositoryBrowser.java +++ b/plugins/scm-hg-plugin/src/main/java/sonia/scm/repository/HgRepositoryBrowser.java @@ -109,14 +109,14 @@ public class HgRepositoryBrowser implements RepositoryBrowser * * @param revision * @param path + * @param output * - * @return * * @throws IOException * @throws RepositoryException */ @Override - public InputStream getContent(String revision, String path) + public void getContent(String revision, String path, OutputStream output) throws IOException, RepositoryException { if (Util.isEmpty(revision)) @@ -141,7 +141,18 @@ public class HgRepositoryBrowser implements RepositoryBrowser logger.debug(msg.toString()); } - return builder.directory(directory).start().getInputStream(); + Process p = builder.directory(directory).start(); + InputStream input = null; + + try + { + input = p.getInputStream(); + IOUtil.copy(input, output); + } + finally + { + IOUtil.close(input); + } } /** diff --git a/plugins/scm-svn-plugin/src/main/java/sonia/scm/repository/SvnRepositoryBrowser.java b/plugins/scm-svn-plugin/src/main/java/sonia/scm/repository/SvnRepositoryBrowser.java index eef15c2767..fb6f287f81 100644 --- a/plugins/scm-svn-plugin/src/main/java/sonia/scm/repository/SvnRepositoryBrowser.java +++ b/plugins/scm-svn-plugin/src/main/java/sonia/scm/repository/SvnRepositoryBrowser.java @@ -50,11 +50,9 @@ import sonia.scm.util.Util; //~--- JDK imports ------------------------------------------------------------ -import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; import java.io.File; import java.io.IOException; -import java.io.InputStream; +import java.io.OutputStream; import java.util.ArrayList; import java.util.Collection; @@ -95,30 +93,23 @@ public class SvnRepositoryBrowser implements RepositoryBrowser * * @param revision * @param path + * @param output * - * @return * * @throws IOException * @throws RepositoryException */ @Override - public InputStream getContent(String revision, String path) + public void getContent(String revision, String path, OutputStream output) throws IOException, RepositoryException { - - // TODO change the api, to remove the ByteArray streams - InputStream content = null; long revisionNumber = getRevisionNumber(revision); SVNRepository svnRepository = null; try { svnRepository = getSvnRepository(); - - ByteArrayOutputStream baos = new ByteArrayOutputStream(); - - svnRepository.getFile(path, revisionNumber, new SVNProperties(), baos); - content = new ByteArrayInputStream(baos.toByteArray()); + svnRepository.getFile(path, revisionNumber, new SVNProperties(), output); } catch (SVNException ex) { @@ -126,10 +117,8 @@ public class SvnRepositoryBrowser implements RepositoryBrowser } finally { - svnRepository.closeSession(); + close(svnRepository); } - - return content; } /** @@ -202,7 +191,7 @@ public class SvnRepositoryBrowser implements RepositoryBrowser } finally { - svnRepository.closeSession(); + close(svnRepository); } return result; @@ -210,6 +199,20 @@ public class SvnRepositoryBrowser implements RepositoryBrowser //~--- methods -------------------------------------------------------------- + /** + * Method description + * + * + * @param svnRepository + */ + private void close(SVNRepository svnRepository) + { + if (svnRepository != null) + { + svnRepository.closeSession(); + } + } + /** * Method description * diff --git a/scm-core/src/main/java/sonia/scm/repository/RepositoryBrowser.java b/scm-core/src/main/java/sonia/scm/repository/RepositoryBrowser.java index e3d9efbefd..7edc92df5f 100644 --- a/scm-core/src/main/java/sonia/scm/repository/RepositoryBrowser.java +++ b/scm-core/src/main/java/sonia/scm/repository/RepositoryBrowser.java @@ -36,7 +36,7 @@ package sonia.scm.repository; //~--- JDK imports ------------------------------------------------------------ import java.io.IOException; -import java.io.InputStream; +import java.io.OutputStream; /** * @@ -52,13 +52,13 @@ public interface RepositoryBrowser * * @param revision * @param path + * @param output * - * @return * * @throws IOException * @throws RepositoryException */ - public InputStream getContent(String revision, String path) + public void getContent(String revision, String path, OutputStream output) throws IOException, RepositoryException;; /** diff --git a/scm-webapp/src/main/java/sonia/scm/api/rest/resources/RepositoryResource.java b/scm-webapp/src/main/java/sonia/scm/api/rest/resources/RepositoryResource.java index 06aaedbb26..fcb2558275 100644 --- a/scm-webapp/src/main/java/sonia/scm/api/rest/resources/RepositoryResource.java +++ b/scm-webapp/src/main/java/sonia/scm/api/rest/resources/RepositoryResource.java @@ -50,6 +50,7 @@ import sonia.scm.repository.ChangesetPreProcessor; import sonia.scm.repository.ChangesetViewer; import sonia.scm.repository.FileObject; import sonia.scm.repository.FileObjectNameComparator; +import sonia.scm.repository.PathNotFoundException; import sonia.scm.repository.Permission; import sonia.scm.repository.PermissionType; import sonia.scm.repository.PermissionUtil; @@ -58,15 +59,14 @@ import sonia.scm.repository.RepositoryBrowser; import sonia.scm.repository.RepositoryException; import sonia.scm.repository.RepositoryHandler; import sonia.scm.repository.RepositoryManager; +import sonia.scm.repository.RevisionNotFoundException; import sonia.scm.util.HttpUtil; -import sonia.scm.util.IOUtil; import sonia.scm.util.Util; import sonia.scm.web.security.WebSecurityContext; //~--- JDK imports ------------------------------------------------------------ import java.io.IOException; -import java.io.InputStream; import java.io.OutputStream; import java.util.ArrayList; @@ -275,34 +275,7 @@ public class RepositoryResource if (browser != null) { - final InputStream content = browser.getContent(revision, path); - - if (content != null) - { - output = new StreamingOutput() - { - @Override - public void write(OutputStream output) - throws IOException, WebApplicationException - { - try - { - IOUtil.copy(content, output); - } - finally - { - IOUtil.close(content); - } - } - }; - } - else if (logger.isWarnEnabled()) - { - logger.warn( - "could not find content, repository: {}, path: {}, revision: {}", - new Object[] { repository.getId(), - path, revision }); - } + output = new BrowserStreamingOutput(browser, revision, path); } else if (logger.isWarnEnabled()) { @@ -516,6 +489,81 @@ public class RepositoryResource PermissionType.OWNER); } + //~--- inner classes -------------------------------------------------------- + + /** + * Class description + * + * + * @version Enter version here..., 11/06/18 + * @author Enter your name here... + */ + private static class BrowserStreamingOutput implements StreamingOutput + { + + /** + * Constructs ... + * + * + * @param browser + * @param revision + * @param path + */ + public BrowserStreamingOutput(RepositoryBrowser browser, String revision, + String path) + { + this.browser = browser; + this.revision = revision; + this.path = path; + } + + //~--- methods ------------------------------------------------------------ + + /** + * Method description + * + * + * @param output + * + * @throws IOException + * @throws WebApplicationException + */ + @Override + public void write(OutputStream output) + throws IOException, WebApplicationException + { + try + { + browser.getContent(revision, path, output); + } + catch (PathNotFoundException ex) + { + throw new WebApplicationException(Response.Status.NOT_FOUND); + } + catch (RevisionNotFoundException ex) + { + throw new WebApplicationException(Response.Status.NOT_FOUND); + } + catch (RepositoryException ex) + { + throw new WebApplicationException( + ex, Response.Status.INTERNAL_SERVER_ERROR); + } + } + + //~--- fields ------------------------------------------------------------- + + /** Field description */ + private RepositoryBrowser browser; + + /** Field description */ + private String path; + + /** Field description */ + private String revision; + } + + //~--- fields --------------------------------------------------------------- /** Field description */ From 72d5c590b90c4905b0250751d4852e9273237602 Mon Sep 17 00:00:00 2001 From: Sebastian Sdorra Date: Sat, 18 Jun 2011 17:02:58 +0200 Subject: [PATCH 36/66] improve BrowserResult api --- .../scm/repository/GitRepositoryBrowser.java | 12 +--- .../src/main/resources/sonia/scm/hgbrowse.py | 35 +++++------ .../scm/repository/SvnRepositoryBrowser.java | 9 +-- .../sonia/scm/repository/BrowserResult.java | 55 ++++++++++++++---- .../java/sonia/scm/repository/FileObject.java | 58 +------------------ .../rest/resources/RepositoryResource.java | 13 ++--- .../sonia.repository.repositorybrowser.js | 2 +- 7 files changed, 69 insertions(+), 115 deletions(-) diff --git a/plugins/scm-git-plugin/src/main/java/sonia/scm/repository/GitRepositoryBrowser.java b/plugins/scm-git-plugin/src/main/java/sonia/scm/repository/GitRepositoryBrowser.java index a56405df0e..fd4fcca923 100644 --- a/plugins/scm-git-plugin/src/main/java/sonia/scm/repository/GitRepositoryBrowser.java +++ b/plugins/scm-git-plugin/src/main/java/sonia/scm/repository/GitRepositoryBrowser.java @@ -130,21 +130,15 @@ public class GitRepositoryBrowser implements RepositoryBrowser treeWalk.addTree(new DirCacheIterator(cache)); result = new BrowserResult(); - FileObject root = new FileObject(); - - root.setDirectory(true); - root.setPath(Util.nonNull(path)); - List files = new ArrayList(); - root.setChildren(files); - result.setFile(root); - result.setRevision(revId.getName()); - while (treeWalk.next()) { files.add(createFileObject(repo, treeWalk)); } + + result.setFiles(files); + result.setRevision(revId.getName()); } finally { diff --git a/plugins/scm-hg-plugin/src/main/resources/sonia/scm/hgbrowse.py b/plugins/scm-hg-plugin/src/main/resources/sonia/scm/hgbrowse.py index 99a0d776fe..c6b99ea826 100644 --- a/plugins/scm-hg-plugin/src/main/resources/sonia/scm/hgbrowse.py +++ b/plugins/scm-hg-plugin/src/main/resources/sonia/scm/hgbrowse.py @@ -58,30 +58,25 @@ print '' print '' print ' ' + revision + '' # todo print tag, and branch -print ' ' -print ' ' + path + '' -print ' ' + name + '' -print ' true' -print ' ' +print ' ' for dir in directories: - print ' ' - print ' ' + getName(dir) + '' - print ' ' + dir + '' - print ' true' - print ' ' + print ' ' + print ' ' + getName(dir) + '' + print ' ' + dir + '' + print ' true' + print ' ' for file in files: linkrev = repo[file.linkrev()] time = int(linkrev.date()[0]) * 1000 desc = linkrev.description() - print ' ' - print ' ' + getName(file.path()) + '' - print ' ' + file.path() + '' - print ' false' - print ' ' + str(file.size()) + '' - print ' ' + str(time).split('.')[0] + '' - print ' ' + desc + '' - print ' ' -print ' ' -print ' ' + print ' ' + print ' ' + getName(file.path()) + '' + print ' ' + file.path() + '' + print ' false' + print ' ' + str(file.size()) + '' + print ' ' + str(time).split('.')[0] + '' + print ' ' + desc + '' + print ' ' +print ' ' print '' diff --git a/plugins/scm-svn-plugin/src/main/java/sonia/scm/repository/SvnRepositoryBrowser.java b/plugins/scm-svn-plugin/src/main/java/sonia/scm/repository/SvnRepositoryBrowser.java index fb6f287f81..d3c4dc02e1 100644 --- a/plugins/scm-svn-plugin/src/main/java/sonia/scm/repository/SvnRepositoryBrowser.java +++ b/plugins/scm-svn-plugin/src/main/java/sonia/scm/repository/SvnRepositoryBrowser.java @@ -176,14 +176,7 @@ public class SvnRepositoryBrowser implements RepositoryBrowser result = new BrowserResult(); result.setRevision(revision); - - // TODO create full root file - FileObject dir = new FileObject(); - - dir.setDirectory(true); - dir.setChildren(children); - dir.setPath(path); - result.setFile(dir); + result.setFiles(children); } catch (SVNException ex) { diff --git a/scm-core/src/main/java/sonia/scm/repository/BrowserResult.java b/scm-core/src/main/java/sonia/scm/repository/BrowserResult.java index d9ec29eab7..f2c49bbe53 100644 --- a/scm-core/src/main/java/sonia/scm/repository/BrowserResult.java +++ b/scm-core/src/main/java/sonia/scm/repository/BrowserResult.java @@ -33,6 +33,15 @@ package sonia.scm.repository; +//~--- JDK imports ------------------------------------------------------------ + +import java.util.Iterator; +import java.util.List; + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.XmlElementWrapper; import javax.xml.bind.annotation.XmlRootElement; /** @@ -40,8 +49,9 @@ import javax.xml.bind.annotation.XmlRootElement; * @author Sebastian Sdorra * @since 1.5 */ -@XmlRootElement(name="browser-result") -public class BrowserResult +@XmlAccessorType(XmlAccessType.FIELD) +@XmlRootElement(name = "browser-result") +public class BrowserResult implements Iterable { /** @@ -57,15 +67,36 @@ public class BrowserResult * @param revision * @param tag * @param branch - * @param file + * @param files */ public BrowserResult(String revision, String tag, String branch, - FileObject file) + List files) { this.revision = revision; this.tag = tag; this.branch = branch; - this.file = file; + this.files = files; + } + + //~--- methods -------------------------------------------------------------- + + /** + * Method description + * + * + * @return + */ + @Override + public Iterator iterator() + { + Iterator it = null; + + if (files != null) + { + it = files.iterator(); + } + + return it; } //~--- get methods ---------------------------------------------------------- @@ -87,9 +118,9 @@ public class BrowserResult * * @return */ - public FileObject getFile() + public List getFiles() { - return file; + return files; } /** @@ -131,11 +162,11 @@ public class BrowserResult * Method description * * - * @param file + * @param files */ - public void setFile(FileObject file) + public void setFiles(List files) { - this.file = file; + this.files = files; } /** @@ -166,7 +197,9 @@ public class BrowserResult private String branch; /** Field description */ - private FileObject file; + @XmlElement(name = "file") + @XmlElementWrapper(name = "files") + private List files; /** Field description */ private String revision; diff --git a/scm-core/src/main/java/sonia/scm/repository/FileObject.java b/scm-core/src/main/java/sonia/scm/repository/FileObject.java index cef6b7e372..215199cc6d 100644 --- a/scm-core/src/main/java/sonia/scm/repository/FileObject.java +++ b/scm-core/src/main/java/sonia/scm/repository/FileObject.java @@ -39,13 +39,6 @@ import sonia.scm.LastModifiedAware; //~--- JDK imports ------------------------------------------------------------ -import java.util.Iterator; -import java.util.List; - -import javax.xml.bind.annotation.XmlAccessType; -import javax.xml.bind.annotation.XmlAccessorType; -import javax.xml.bind.annotation.XmlElement; -import javax.xml.bind.annotation.XmlElementWrapper; import javax.xml.bind.annotation.XmlRootElement; /** @@ -54,42 +47,9 @@ import javax.xml.bind.annotation.XmlRootElement; * @since 1.5 */ @XmlRootElement(name = "file") -@XmlAccessorType(XmlAccessType.FIELD) -public class FileObject implements LastModifiedAware, Iterable +public class FileObject implements LastModifiedAware { - /** - * Method description - * - * - * @return - */ - @Override - public Iterator iterator() - { - Iterator iterator = null; - - if (children != null) - { - iterator = children.iterator(); - } - - return iterator; - } - - //~--- get methods ---------------------------------------------------------- - - /** - * Method description - * - * - * @return - */ - public List getChildren() - { - return children; - } - /** * Method description * @@ -159,17 +119,6 @@ public class FileObject implements LastModifiedAware, Iterable //~--- set methods ---------------------------------------------------------- - /** - * Method description - * - * - * @param children - */ - public void setChildren(List children) - { - this.children = children; - } - /** * Method description * @@ -238,11 +187,6 @@ public class FileObject implements LastModifiedAware, Iterable //~--- fields --------------------------------------------------------------- - /** Field description */ - @XmlElement(name = "file") - @XmlElementWrapper(name = "children") - private List children; - /** Field description */ private String description; diff --git a/scm-webapp/src/main/java/sonia/scm/api/rest/resources/RepositoryResource.java b/scm-webapp/src/main/java/sonia/scm/api/rest/resources/RepositoryResource.java index fcb2558275..857b56aef1 100644 --- a/scm-webapp/src/main/java/sonia/scm/api/rest/resources/RepositoryResource.java +++ b/scm-webapp/src/main/java/sonia/scm/api/rest/resources/RepositoryResource.java @@ -460,16 +460,11 @@ public class RepositoryResource */ private void sort(BrowserResult result) { - FileObject file = result.getFile(); + List files = result.getFiles(); - if (file != null) + if (files != null) { - List children = file.getChildren(); - - if (children != null) - { - Collections.sort(children, FileObjectNameComparator.instance); - } + Collections.sort(files, FileObjectNameComparator.instance); } } @@ -496,7 +491,7 @@ public class RepositoryResource * * * @version Enter version here..., 11/06/18 - * @author Enter your name here... + * @author Enter your name here... */ private static class BrowserStreamingOutput implements StreamingOutput { diff --git a/scm-webapp/src/main/webapp/resources/js/repository/sonia.repository.repositorybrowser.js b/scm-webapp/src/main/webapp/resources/js/repository/sonia.repository.repositorybrowser.js index d4dd7a0422..61c83c3f95 100644 --- a/scm-webapp/src/main/webapp/resources/js/repository/sonia.repository.repositorybrowser.js +++ b/scm-webapp/src/main/webapp/resources/js/repository/sonia.repository.repositorybrowser.js @@ -53,7 +53,7 @@ Sonia.repository.RepositoryBrowser = Ext.extend(Ext.grid.GridPanel, { method: 'GET' }), fields: ['path', 'name', 'length', 'lastModified', 'directory', 'description'], - root: 'file.children', + root: 'files', idProperty: 'path', autoLoad: true, autoDestroy: true, From 381118c244fa6fda759de75664075d3d8f5a625b Mon Sep 17 00:00:00 2001 From: Sebastian Sdorra Date: Sat, 18 Jun 2011 17:27:48 +0200 Subject: [PATCH 37/66] improve logging --- .../scm/api/rest/resources/RepositoryResource.java | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/scm-webapp/src/main/java/sonia/scm/api/rest/resources/RepositoryResource.java b/scm-webapp/src/main/java/sonia/scm/api/rest/resources/RepositoryResource.java index 857b56aef1..a98ce7d90e 100644 --- a/scm-webapp/src/main/java/sonia/scm/api/rest/resources/RepositoryResource.java +++ b/scm-webapp/src/main/java/sonia/scm/api/rest/resources/RepositoryResource.java @@ -533,14 +533,26 @@ public class RepositoryResource } catch (PathNotFoundException ex) { + if (logger.isWarnEnabled()) + { + logger.warn("could not find path {}", ex.getPath()); + } + throw new WebApplicationException(Response.Status.NOT_FOUND); } catch (RevisionNotFoundException ex) { + if (logger.isWarnEnabled()) + { + logger.warn("could not find revision {}", ex.getRevision()); + } + throw new WebApplicationException(Response.Status.NOT_FOUND); } catch (RepositoryException ex) { + logger.error("could not write content to page", ex); + throw new WebApplicationException( ex, Response.Status.INTERNAL_SERVER_ERROR); } From a446a3063c523eb51120939e5316622a2116a938 Mon Sep 17 00:00:00 2001 From: Sebastian Sdorra Date: Sat, 18 Jun 2011 17:28:33 +0200 Subject: [PATCH 38/66] implement git getContent for repository browser --- .../scm/repository/GitRepositoryBrowser.java | 82 +++++++++++++++++-- 1 file changed, 74 insertions(+), 8 deletions(-) diff --git a/plugins/scm-git-plugin/src/main/java/sonia/scm/repository/GitRepositoryBrowser.java b/plugins/scm-git-plugin/src/main/java/sonia/scm/repository/GitRepositoryBrowser.java index fd4fcca923..70ca592b89 100644 --- a/plugins/scm-git-plugin/src/main/java/sonia/scm/repository/GitRepositoryBrowser.java +++ b/plugins/scm-git-plugin/src/main/java/sonia/scm/repository/GitRepositoryBrowser.java @@ -35,12 +35,15 @@ package sonia.scm.repository; //~--- non-JDK imports -------------------------------------------------------- +import org.eclipse.jgit.api.Git; import org.eclipse.jgit.dircache.DirCache; import org.eclipse.jgit.dircache.DirCacheIterator; import org.eclipse.jgit.lib.Constants; import org.eclipse.jgit.lib.ObjectId; import org.eclipse.jgit.lib.ObjectLoader; import org.eclipse.jgit.lib.RepositoryCache; +import org.eclipse.jgit.revwalk.RevCommit; +import org.eclipse.jgit.revwalk.RevTree; import org.eclipse.jgit.revwalk.RevWalk; import org.eclipse.jgit.treewalk.TreeWalk; import org.eclipse.jgit.util.FS; @@ -95,7 +98,44 @@ public class GitRepositoryBrowser implements RepositoryBrowser public void getContent(String revision, String path, OutputStream output) throws IOException, RepositoryException { - throw new UnsupportedOperationException("Not supported yet."); + File directory = handler.getDirectory(repository); + org.eclipse.jgit.lib.Repository repo = open(directory); + + try + { + ObjectId revId = getRevisionId(repo, revision); + RevWalk revWalk = new RevWalk(repo); + RevCommit entry = revWalk.parseCommit(revId); + RevTree revTree = entry.getTree(); + TreeWalk treeWalk = TreeWalk.forPath(repo, path, revTree); + + if (treeWalk.next()) + { + + // Path exists + if (treeWalk.getFileMode(0).getObjectType() == Constants.OBJ_BLOB) + { + ObjectId blobId = treeWalk.getObjectId(0); + ObjectLoader loader = repo.open(blobId); + + loader.copyTo(output); + } + else + { + + // Not a blob, its something else (tree, gitlink) + throw new PathNotFoundException(path); + } + } + else + { + throw new PathNotFoundException(path); + } + } + finally + { + close(repo); + } } /** @@ -116,9 +156,7 @@ public class GitRepositoryBrowser implements RepositoryBrowser { BrowserResult result = null; File directory = handler.getDirectory(repository); - org.eclipse.jgit.lib.Repository repo = - RepositoryCache.open(RepositoryCache.FileKey.lenient(directory, - FS.DETECTED), true); + org.eclipse.jgit.lib.Repository repo = open(directory); try { @@ -142,10 +180,7 @@ public class GitRepositoryBrowser implements RepositoryBrowser } finally { - if (repo != null) - { - repo.close(); - } + close(repo); } return result; @@ -153,6 +188,20 @@ public class GitRepositoryBrowser implements RepositoryBrowser //~--- methods -------------------------------------------------------------- + /** + * Method description + * + * + * @param repo + */ + private void close(org.eclipse.jgit.lib.Repository repo) + { + if (repo != null) + { + repo.close(); + } + } + /** * Method description * @@ -184,6 +233,23 @@ public class GitRepositoryBrowser implements RepositoryBrowser return file; } + /** + * Method description + * + * + * @param directory + * + * @return + * + * @throws IOException + */ + private org.eclipse.jgit.lib.Repository open(File directory) + throws IOException + { + return RepositoryCache.open(RepositoryCache.FileKey.lenient(directory, + FS.DETECTED), true); + } + //~--- get methods ---------------------------------------------------------- /** From db7a653f836ea4abd1c631db727707471703d71e Mon Sep 17 00:00:00 2001 From: Sebastian Sdorra Date: Sun, 19 Jun 2011 12:52:50 +0200 Subject: [PATCH 39/66] fix java multiline comments --- .../syntaxhighlighter/scripts/shBrushJava.js | 20 ++----------------- 1 file changed, 2 insertions(+), 18 deletions(-) diff --git a/scm-webapp/src/main/webapp/resources/syntaxhighlighter/scripts/shBrushJava.js b/scm-webapp/src/main/webapp/resources/syntaxhighlighter/scripts/shBrushJava.js index d692fd6382..1fb39cfa3a 100644 --- a/scm-webapp/src/main/webapp/resources/syntaxhighlighter/scripts/shBrushJava.js +++ b/scm-webapp/src/main/webapp/resources/syntaxhighlighter/scripts/shBrushJava.js @@ -1,19 +1,3 @@ -/** - * SyntaxHighlighter - * http://alexgorbatchev.com/SyntaxHighlighter - * - * SyntaxHighlighter is donationware. If you are using it, please donate. - * http://alexgorbatchev.com/SyntaxHighlighter/donate.html - * - * @version - * 3.0.83 (July 02 2010) - * - * @copyright - * Copyright (C) 2004-2010 Alex Gorbatchev. - * - * @license - * Dual licensed under the MIT and GPL licenses. - */ ;(function() { // CommonJS @@ -31,8 +15,8 @@ this.regexList = [ { regex: SyntaxHighlighter.regexLib.singleLineCComments, css: 'comments' }, // one line comments - { regex: /\/\*([^\*][\s\S]*)?\*\//gm, css: 'comments' }, // multiline comments - { regex: /\/\*(?!\*\/)\*[\s\S]*?\*\//gm, css: 'preprocessor' }, // documentation comments + { regex: /\/\*\*?[\s\S]*?\*\//gm, css: 'preprocessor' }, // documentation comments + { regex: SyntaxHighlighter.regexLib.multiLineCComments, css: 'comments' }, // multiline comments { regex: SyntaxHighlighter.regexLib.doubleQuotedString, css: 'string' }, // strings { regex: SyntaxHighlighter.regexLib.singleQuotedString, css: 'string' }, // strings { regex: /\b([\d]+(\.[\d]+)?|0x[a-f0-9]+)\b/gi, css: 'value' }, // numbers From aef03e237d831ab5876214eae099c6efff9cea30 Mon Sep 17 00:00:00 2001 From: Sebastian Sdorra Date: Sun, 19 Jun 2011 13:02:04 +0200 Subject: [PATCH 40/66] fix getName method of repositorybrowser --- .../js/repository/sonia.repository.repositorybrowser.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scm-webapp/src/main/webapp/resources/js/repository/sonia.repository.repositorybrowser.js b/scm-webapp/src/main/webapp/resources/js/repository/sonia.repository.repositorybrowser.js index 61c83c3f95..5ca2e00502 100644 --- a/scm-webapp/src/main/webapp/resources/js/repository/sonia.repository.repositorybrowser.js +++ b/scm-webapp/src/main/webapp/resources/js/repository/sonia.repository.repositorybrowser.js @@ -176,7 +176,7 @@ Sonia.repository.RepositoryBrowser = Ext.extend(Ext.grid.GridPanel, { var name = path; var index = path.lastIndexOf('/'); if ( index > 0 ){ - name = path.substr(0, path.length - 1); + name = path.substr(index +1); } return name }, From 384a15bf99a8b4f7cab33fdc8fcff9517957eeb7 Mon Sep 17 00:00:00 2001 From: Sebastian Sdorra Date: Sun, 19 Jun 2011 13:24:19 +0200 Subject: [PATCH 41/66] enable tab scrolling --- scm-webapp/src/main/webapp/resources/js/sonia.scm.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/scm-webapp/src/main/webapp/resources/js/sonia.scm.js b/scm-webapp/src/main/webapp/resources/js/sonia.scm.js index a7cba94a45..dbbde17dc1 100644 --- a/scm-webapp/src/main/webapp/resources/js/sonia.scm.js +++ b/scm-webapp/src/main/webapp/resources/js/sonia.scm.js @@ -441,7 +441,8 @@ Ext.onReady(function(){ var mainTabPanel = new Ext.TabPanel({ id: 'mainTabPanel', region: 'center', - deferredRender: false + deferredRender: false, + enableTabScroll: true }); new Ext.Viewport({ From 9d62147400655639b6faf857749d7952c41e5cfa Mon Sep 17 00:00:00 2001 From: Sebastian Sdorra Date: Sun, 19 Jun 2011 13:28:16 +0200 Subject: [PATCH 42/66] fix missing brush for text files --- .../resources/js/panel/sonia.panel.syntaxhighlighterpanel.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scm-webapp/src/main/webapp/resources/js/panel/sonia.panel.syntaxhighlighterpanel.js b/scm-webapp/src/main/webapp/resources/js/panel/sonia.panel.syntaxhighlighterpanel.js index 62af6545a7..cabf42d8f8 100644 --- a/scm-webapp/src/main/webapp/resources/js/panel/sonia.panel.syntaxhighlighterpanel.js +++ b/scm-webapp/src/main/webapp/resources/js/panel/sonia.panel.syntaxhighlighterpanel.js @@ -94,7 +94,7 @@ Sonia.panel.SyntaxHighlighterPanel = Ext.extend(Ext.Panel, { fileName: 'shBrushPhp.js' },{ name: 'Plain Text', - aliases: ['plain', 'text', 'txt'], + aliases: ['plain', 'text'], fileName: 'shBrushPlain.js' },{ name: 'PowerShell', From 45eeb2912b36807868804450cb56b2cd27b4913e Mon Sep 17 00:00:00 2001 From: Sebastian Sdorra Date: Sun, 19 Jun 2011 13:33:54 +0200 Subject: [PATCH 43/66] improve error handling --- scm-webapp/src/main/webapp/resources/js/i18n/de.js | 9 +++++++++ .../js/panel/sonia.panel.syntaxhighlighterpanel.js | 11 +++++++++-- 2 files changed, 18 insertions(+), 2 deletions(-) diff --git a/scm-webapp/src/main/webapp/resources/js/i18n/de.js b/scm-webapp/src/main/webapp/resources/js/i18n/de.js index 0a0caf3058..51ffdcde20 100644 --- a/scm-webapp/src/main/webapp/resources/js/i18n/de.js +++ b/scm-webapp/src/main/webapp/resources/js/i18n/de.js @@ -501,3 +501,12 @@ if (Sonia.scm.Main){ }); } + +if (Sonia.panel.SyntaxHighlighterPanel){ + + Ext.override(Sonia.panel.SyntaxHighlighterPanel, { + loadErrorTitleText: 'Fehler', + loadErrorMsgText: 'Die Datei konnte nicht geladen werden' + }); + +} diff --git a/scm-webapp/src/main/webapp/resources/js/panel/sonia.panel.syntaxhighlighterpanel.js b/scm-webapp/src/main/webapp/resources/js/panel/sonia.panel.syntaxhighlighterpanel.js index cabf42d8f8..7790b06704 100644 --- a/scm-webapp/src/main/webapp/resources/js/panel/sonia.panel.syntaxhighlighterpanel.js +++ b/scm-webapp/src/main/webapp/resources/js/panel/sonia.panel.syntaxhighlighterpanel.js @@ -137,6 +137,9 @@ Sonia.panel.SyntaxHighlighterPanel = Ext.extend(Ext.Panel, { shPath: 'resources/syntaxhighlighter', contentUrl: null, + loadErrorTitleText: 'Error', + loadErrorMsgText: 'Could not load file', + contentLoaded: false, scriptsLoaded: false, @@ -211,8 +214,12 @@ Sonia.panel.SyntaxHighlighterPanel = Ext.extend(Ext.Panel, { this.contentLoaded = true; this.highlight(); }, - failure: function(){ - // TODO + failure: function(result){ + main.handleFailure( + result.status, + this.loadErrorTitleText, + this.loadErrorMsgText + ); } }); }, From 3d9f8e3314246d6721fa8c4afcd8e751579484e5 Mon Sep 17 00:00:00 2001 From: Sebastian Sdorra Date: Sun, 19 Jun 2011 13:36:26 +0200 Subject: [PATCH 44/66] improve logging --- .../src/main/webapp/resources/js/rest/sonia.rest.jsonstore.js | 3 +++ 1 file changed, 3 insertions(+) diff --git a/scm-webapp/src/main/webapp/resources/js/rest/sonia.rest.jsonstore.js b/scm-webapp/src/main/webapp/resources/js/rest/sonia.rest.jsonstore.js index f2b447a7ec..8f935fa27e 100644 --- a/scm-webapp/src/main/webapp/resources/js/rest/sonia.rest.jsonstore.js +++ b/scm-webapp/src/main/webapp/resources/js/rest/sonia.rest.jsonstore.js @@ -49,6 +49,9 @@ Sonia.rest.JsonStore = Ext.extend( Ext.data.JsonStore, { } this.removeAll(); } else { + if (debug){ + console.debug( 'error during store load, status: ' + status ); + } main.handleFailure( status, this.errorTitleText, From da8c28cb55c8a843e7709f9aa2919c8fa9f7b9bc Mon Sep 17 00:00:00 2001 From: Sebastian Sdorra Date: Sun, 19 Jun 2011 13:46:46 +0200 Subject: [PATCH 45/66] fix getContent method of git repository browser --- .../java/sonia/scm/repository/GitRepositoryBrowser.java | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/plugins/scm-git-plugin/src/main/java/sonia/scm/repository/GitRepositoryBrowser.java b/plugins/scm-git-plugin/src/main/java/sonia/scm/repository/GitRepositoryBrowser.java index 70ca592b89..1e80410edb 100644 --- a/plugins/scm-git-plugin/src/main/java/sonia/scm/repository/GitRepositoryBrowser.java +++ b/plugins/scm-git-plugin/src/main/java/sonia/scm/repository/GitRepositoryBrowser.java @@ -46,6 +46,8 @@ import org.eclipse.jgit.revwalk.RevCommit; import org.eclipse.jgit.revwalk.RevTree; import org.eclipse.jgit.revwalk.RevWalk; import org.eclipse.jgit.treewalk.TreeWalk; +import org.eclipse.jgit.treewalk.filter.PathFilter; +import org.eclipse.jgit.treewalk.filter.TreeFilter; import org.eclipse.jgit.util.FS; import sonia.scm.util.Util; @@ -107,7 +109,10 @@ public class GitRepositoryBrowser implements RepositoryBrowser RevWalk revWalk = new RevWalk(repo); RevCommit entry = revWalk.parseCommit(revId); RevTree revTree = entry.getTree(); - TreeWalk treeWalk = TreeWalk.forPath(repo, path, revTree); + TreeWalk treeWalk = new TreeWalk(repo); + + treeWalk.addTree(revTree); + treeWalk.setFilter(PathFilter.create(path)); if (treeWalk.next()) { From 3c367d225bca1a4d3b2f56d5034b06672d188bd5 Mon Sep 17 00:00:00 2001 From: Sebastian Sdorra Date: Tue, 21 Jun 2011 17:22:42 +0200 Subject: [PATCH 46/66] release treewalk after iteration --- .../scm/repository/GitRepositoryBrowser.java | 25 ++++++++++++++++--- 1 file changed, 21 insertions(+), 4 deletions(-) diff --git a/plugins/scm-git-plugin/src/main/java/sonia/scm/repository/GitRepositoryBrowser.java b/plugins/scm-git-plugin/src/main/java/sonia/scm/repository/GitRepositoryBrowser.java index 1e80410edb..9a41c2c47e 100644 --- a/plugins/scm-git-plugin/src/main/java/sonia/scm/repository/GitRepositoryBrowser.java +++ b/plugins/scm-git-plugin/src/main/java/sonia/scm/repository/GitRepositoryBrowser.java @@ -35,7 +35,6 @@ package sonia.scm.repository; //~--- non-JDK imports -------------------------------------------------------- -import org.eclipse.jgit.api.Git; import org.eclipse.jgit.dircache.DirCache; import org.eclipse.jgit.dircache.DirCacheIterator; import org.eclipse.jgit.lib.Constants; @@ -47,7 +46,6 @@ import org.eclipse.jgit.revwalk.RevTree; import org.eclipse.jgit.revwalk.RevWalk; import org.eclipse.jgit.treewalk.TreeWalk; import org.eclipse.jgit.treewalk.filter.PathFilter; -import org.eclipse.jgit.treewalk.filter.TreeFilter; import org.eclipse.jgit.util.FS; import sonia.scm.util.Util; @@ -102,14 +100,16 @@ public class GitRepositoryBrowser implements RepositoryBrowser { File directory = handler.getDirectory(repository); org.eclipse.jgit.lib.Repository repo = open(directory); + TreeWalk treeWalk = null; try { + treeWalk = new TreeWalk(repo); + ObjectId revId = getRevisionId(repo, revision); RevWalk revWalk = new RevWalk(repo); RevCommit entry = revWalk.parseCommit(revId); RevTree revTree = entry.getTree(); - TreeWalk treeWalk = new TreeWalk(repo); treeWalk.addTree(revTree); treeWalk.setFilter(PathFilter.create(path)); @@ -140,6 +140,7 @@ public class GitRepositoryBrowser implements RepositoryBrowser finally { close(repo); + release(treeWalk); } } @@ -162,13 +163,14 @@ public class GitRepositoryBrowser implements RepositoryBrowser BrowserResult result = null; File directory = handler.getDirectory(repository); org.eclipse.jgit.lib.Repository repo = open(directory); + TreeWalk treeWalk = null; try { ObjectId revId = getRevisionId(repo, revision); DirCache cache = new DirCache(directory, FS.DETECTED); - TreeWalk treeWalk = new TreeWalk(repo); + treeWalk = new TreeWalk(repo); treeWalk.addTree(new RevWalk(repo).parseTree(revId)); treeWalk.addTree(new DirCacheIterator(cache)); result = new BrowserResult(); @@ -186,6 +188,7 @@ public class GitRepositoryBrowser implements RepositoryBrowser finally { close(repo); + release(treeWalk); } return result; @@ -255,6 +258,20 @@ public class GitRepositoryBrowser implements RepositoryBrowser FS.DETECTED), true); } + /** + * Method description + * + * + * @param walk + */ + private void release(TreeWalk walk) + { + if (walk != null) + { + walk.release(); + } + } + //~--- get methods ---------------------------------------------------------- /** From 0a343159a9e04c33281d569b554da0faa85e3278 Mon Sep 17 00:00:00 2001 From: Sebastian Sdorra Date: Tue, 21 Jun 2011 17:41:05 +0200 Subject: [PATCH 47/66] fetch latest revcommit --- .../scm/repository/GitChangesetViewer.java | 4 +- .../scm/repository/GitRepositoryBrowser.java | 74 +++++++++++++++++-- .../java/sonia/scm/repository/GitUtil.java | 63 ++++++++++++++++ 3 files changed, 131 insertions(+), 10 deletions(-) create mode 100644 plugins/scm-git-plugin/src/main/java/sonia/scm/repository/GitUtil.java diff --git a/plugins/scm-git-plugin/src/main/java/sonia/scm/repository/GitChangesetViewer.java b/plugins/scm-git-plugin/src/main/java/sonia/scm/repository/GitChangesetViewer.java index f87683c8f4..951c3d9967 100644 --- a/plugins/scm-git-plugin/src/main/java/sonia/scm/repository/GitChangesetViewer.java +++ b/plugins/scm-git-plugin/src/main/java/sonia/scm/repository/GitChangesetViewer.java @@ -202,9 +202,7 @@ public class GitChangesetViewer implements ChangesetViewer throws IOException { String id = commit.getId().abbreviate(ID_LENGTH).name(); - long date = commit.getCommitTime(); - - date = date * 1000; + long date = GitUtil.getCommitTime(commit); PersonIdent authorIndent = commit.getCommitterIdent(); Person author = new Person(authorIndent.getName(), diff --git a/plugins/scm-git-plugin/src/main/java/sonia/scm/repository/GitRepositoryBrowser.java b/plugins/scm-git-plugin/src/main/java/sonia/scm/repository/GitRepositoryBrowser.java index 9a41c2c47e..680c15d4e3 100644 --- a/plugins/scm-git-plugin/src/main/java/sonia/scm/repository/GitRepositoryBrowser.java +++ b/plugins/scm-git-plugin/src/main/java/sonia/scm/repository/GitRepositoryBrowser.java @@ -35,6 +35,7 @@ package sonia.scm.repository; //~--- non-JDK imports -------------------------------------------------------- +import org.eclipse.jgit.api.Git; import org.eclipse.jgit.dircache.DirCache; import org.eclipse.jgit.dircache.DirCacheIterator; import org.eclipse.jgit.lib.Constants; @@ -48,6 +49,9 @@ import org.eclipse.jgit.treewalk.TreeWalk; import org.eclipse.jgit.treewalk.filter.PathFilter; import org.eclipse.jgit.util.FS; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + import sonia.scm.util.Util; //~--- JDK imports ------------------------------------------------------------ @@ -57,6 +61,7 @@ import java.io.IOException; import java.io.OutputStream; import java.util.ArrayList; +import java.util.Iterator; import java.util.List; /** @@ -66,6 +71,12 @@ import java.util.List; public class GitRepositoryBrowser implements RepositoryBrowser { + /** the logger for GitRepositoryBrowser */ + private static final Logger logger = + LoggerFactory.getLogger(GitRepositoryBrowser.class); + + //~--- constructors --------------------------------------------------------- + /** * Constructs ... * @@ -163,6 +174,7 @@ public class GitRepositoryBrowser implements RepositoryBrowser BrowserResult result = null; File directory = handler.getDirectory(repository); org.eclipse.jgit.lib.Repository repo = open(directory); + Git git = new Git(repo); TreeWalk treeWalk = null; try @@ -179,7 +191,7 @@ public class GitRepositoryBrowser implements RepositoryBrowser while (treeWalk.next()) { - files.add(createFileObject(repo, treeWalk)); + files.add(createFileObject(git, revId, treeWalk)); } result.setFiles(files); @@ -214,29 +226,41 @@ public class GitRepositoryBrowser implements RepositoryBrowser * Method description * * - * @param repo + * + * @param git + * @param revId * @param treeWalk * * @return * * @throws IOException */ - private FileObject createFileObject(org.eclipse.jgit.lib.Repository repo, + private FileObject createFileObject(Git git, ObjectId revId, TreeWalk treeWalk) throws IOException { FileObject file = new FileObject(); + String path = treeWalk.getPathString(); file.setName(treeWalk.getNameString()); - file.setPath(treeWalk.getPathString()); + file.setPath(path); - ObjectLoader loader = repo.open(treeWalk.getObjectId(0)); + ObjectLoader loader = git.getRepository().open(treeWalk.getObjectId(0)); file.setDirectory(loader.getType() == Constants.OBJ_TREE); file.setLength(loader.getSize()); - // TODO - file.setLastModified(System.currentTimeMillis()); + RevCommit commit = getLatestCommit(git, revId, path); + + if (commit != null) + { + file.setLastModified(GitUtil.getCommitTime(commit)); + file.setDescription(commit.getShortMessage()); + } + else if (logger.isWarnEnabled()) + { + logger.warn("could not find latest commit for {} on {}", path, revId); + } return file; } @@ -274,6 +298,42 @@ public class GitRepositoryBrowser implements RepositoryBrowser //~--- get methods ---------------------------------------------------------- + /** + * Method description + * + * + * @param git + * @param revId + * @param path + * + * @return + */ + private RevCommit getLatestCommit(Git git, ObjectId revId, String path) + { + RevCommit commit = null; + + try + { + Iterable iterable = git.log().add(revId).addPath(path).call(); + + if (iterable != null) + { + Iterator it = iterable.iterator(); + + if ((it != null) && it.hasNext()) + { + commit = it.next(); + } + } + } + catch (Exception ex) + { + logger.error("could not fetch latest commit", ex); + } + + return commit; + } + /** * Method description * diff --git a/plugins/scm-git-plugin/src/main/java/sonia/scm/repository/GitUtil.java b/plugins/scm-git-plugin/src/main/java/sonia/scm/repository/GitUtil.java new file mode 100644 index 0000000000..d1eaaba6dc --- /dev/null +++ b/plugins/scm-git-plugin/src/main/java/sonia/scm/repository/GitUtil.java @@ -0,0 +1,63 @@ +/** + * Copyright (c) 2010, Sebastian Sdorra + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of SCM-Manager; nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 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 REGENTS 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. + * + * http://bitbucket.org/sdorra/scm-manager + * + */ + + + +package sonia.scm.repository; + +//~--- non-JDK imports -------------------------------------------------------- + +import org.eclipse.jgit.revwalk.RevCommit; + +/** + * + * @author Sebastian Sdorra + */ +public class GitUtil +{ + + /** + * Method description + * + * + * @param commit + * + * @return + */ + public static long getCommitTime(RevCommit commit) + { + long date = commit.getCommitTime(); + + date = date * 1000; + + return date; + } +} From d80ef3c27aa03ce29d05a347fd6c4cf4db5f1c5c Mon Sep 17 00:00:00 2001 From: Sebastian Sdorra Date: Tue, 21 Jun 2011 17:45:14 +0200 Subject: [PATCH 48/66] improve GitUtil --- .../scm/repository/GitRepositoryBrowser.java | 99 +++-------------- .../java/sonia/scm/repository/GitUtil.java | 104 ++++++++++++++++++ 2 files changed, 117 insertions(+), 86 deletions(-) diff --git a/plugins/scm-git-plugin/src/main/java/sonia/scm/repository/GitRepositoryBrowser.java b/plugins/scm-git-plugin/src/main/java/sonia/scm/repository/GitRepositoryBrowser.java index 680c15d4e3..20d8ea97ca 100644 --- a/plugins/scm-git-plugin/src/main/java/sonia/scm/repository/GitRepositoryBrowser.java +++ b/plugins/scm-git-plugin/src/main/java/sonia/scm/repository/GitRepositoryBrowser.java @@ -41,7 +41,6 @@ import org.eclipse.jgit.dircache.DirCacheIterator; import org.eclipse.jgit.lib.Constants; import org.eclipse.jgit.lib.ObjectId; import org.eclipse.jgit.lib.ObjectLoader; -import org.eclipse.jgit.lib.RepositoryCache; import org.eclipse.jgit.revwalk.RevCommit; import org.eclipse.jgit.revwalk.RevTree; import org.eclipse.jgit.revwalk.RevWalk; @@ -52,8 +51,6 @@ import org.eclipse.jgit.util.FS; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import sonia.scm.util.Util; - //~--- JDK imports ------------------------------------------------------------ import java.io.File; @@ -110,15 +107,18 @@ public class GitRepositoryBrowser implements RepositoryBrowser throws IOException, RepositoryException { File directory = handler.getDirectory(repository); - org.eclipse.jgit.lib.Repository repo = open(directory); + org.eclipse.jgit.lib.Repository repo = GitUtil.open(directory); TreeWalk treeWalk = null; + RevWalk revWalk = null; try { treeWalk = new TreeWalk(repo); - ObjectId revId = getRevisionId(repo, revision); - RevWalk revWalk = new RevWalk(repo); + ObjectId revId = GitUtil.getRevisionId(repo, revision); + + revWalk = new RevWalk(repo); + RevCommit entry = revWalk.parseCommit(revId); RevTree revTree = entry.getTree(); @@ -150,8 +150,9 @@ public class GitRepositoryBrowser implements RepositoryBrowser } finally { - close(repo); - release(treeWalk); + GitUtil.release(revWalk); + GitUtil.release(treeWalk); + GitUtil.close(repo); } } @@ -173,13 +174,13 @@ public class GitRepositoryBrowser implements RepositoryBrowser { BrowserResult result = null; File directory = handler.getDirectory(repository); - org.eclipse.jgit.lib.Repository repo = open(directory); + org.eclipse.jgit.lib.Repository repo = GitUtil.open(directory); Git git = new Git(repo); TreeWalk treeWalk = null; try { - ObjectId revId = getRevisionId(repo, revision); + ObjectId revId = GitUtil.getRevisionId(repo, revision); DirCache cache = new DirCache(directory, FS.DETECTED); treeWalk = new TreeWalk(repo); @@ -199,8 +200,8 @@ public class GitRepositoryBrowser implements RepositoryBrowser } finally { - close(repo); - release(treeWalk); + GitUtil.close(repo); + GitUtil.release(treeWalk); } return result; @@ -208,20 +209,6 @@ public class GitRepositoryBrowser implements RepositoryBrowser //~--- methods -------------------------------------------------------------- - /** - * Method description - * - * - * @param repo - */ - private void close(org.eclipse.jgit.lib.Repository repo) - { - if (repo != null) - { - repo.close(); - } - } - /** * Method description * @@ -265,37 +252,6 @@ public class GitRepositoryBrowser implements RepositoryBrowser return file; } - /** - * Method description - * - * - * @param directory - * - * @return - * - * @throws IOException - */ - private org.eclipse.jgit.lib.Repository open(File directory) - throws IOException - { - return RepositoryCache.open(RepositoryCache.FileKey.lenient(directory, - FS.DETECTED), true); - } - - /** - * Method description - * - * - * @param walk - */ - private void release(TreeWalk walk) - { - if (walk != null) - { - walk.release(); - } - } - //~--- get methods ---------------------------------------------------------- /** @@ -334,35 +290,6 @@ public class GitRepositoryBrowser implements RepositoryBrowser return commit; } - /** - * Method description - * - * - * @param repo - * @param revision - * - * @return - * - * @throws IOException - */ - private ObjectId getRevisionId(org.eclipse.jgit.lib.Repository repo, - String revision) - throws IOException - { - ObjectId revId = null; - - if (Util.isNotEmpty(revision)) - { - revId = repo.resolve(revision); - } - else - { - revId = repo.resolve(Constants.HEAD); - } - - return revId; - } - //~--- fields --------------------------------------------------------------- /** Field description */ diff --git a/plugins/scm-git-plugin/src/main/java/sonia/scm/repository/GitUtil.java b/plugins/scm-git-plugin/src/main/java/sonia/scm/repository/GitUtil.java index d1eaaba6dc..231dc9e840 100644 --- a/plugins/scm-git-plugin/src/main/java/sonia/scm/repository/GitUtil.java +++ b/plugins/scm-git-plugin/src/main/java/sonia/scm/repository/GitUtil.java @@ -35,7 +35,20 @@ package sonia.scm.repository; //~--- non-JDK imports -------------------------------------------------------- +import java.io.File; +import org.eclipse.jgit.lib.Constants; +import org.eclipse.jgit.lib.ObjectId; import org.eclipse.jgit.revwalk.RevCommit; +import org.eclipse.jgit.revwalk.RevWalk; +import org.eclipse.jgit.treewalk.TreeWalk; + +import sonia.scm.util.Util; + +//~--- JDK imports ------------------------------------------------------------ + +import java.io.IOException; +import org.eclipse.jgit.lib.RepositoryCache; +import org.eclipse.jgit.util.FS; /** * @@ -44,6 +57,50 @@ import org.eclipse.jgit.revwalk.RevCommit; public class GitUtil { + /** + * Method description + * + * + * @param repo + */ + public static void close(org.eclipse.jgit.lib.Repository repo) + { + if (repo != null) + { + repo.close(); + } + } + + /** + * Method description + * + * + * @param walk + */ + public static void release(TreeWalk walk) + { + if (walk != null) + { + walk.release(); + } + } + + /** + * Method description + * + * + * @param walk + */ + public static void release(RevWalk walk) + { + if (walk != null) + { + walk.release(); + } + } + + //~--- get methods ---------------------------------------------------------- + /** * Method description * @@ -60,4 +117,51 @@ public class GitUtil return date; } + + + /** + * Method description + * + * + * @param directory + * + * @return + * + * @throws IOException + */ + public static org.eclipse.jgit.lib.Repository open(File directory) + throws IOException + { + return RepositoryCache.open(RepositoryCache.FileKey.lenient(directory, + FS.DETECTED), true); + } + + /** + * Method description + * + * + * @param repo + * @param revision + * + * @return + * + * @throws IOException + */ + public static ObjectId getRevisionId(org.eclipse.jgit.lib.Repository repo, + String revision) + throws IOException + { + ObjectId revId = null; + + if (Util.isNotEmpty(revision)) + { + revId = repo.resolve(revision); + } + else + { + revId = repo.resolve(Constants.HEAD); + } + + return revId; + } } From bef3d08eb57c5f4315a722e5c0f9a2fed744969d Mon Sep 17 00:00:00 2001 From: Sebastian Sdorra Date: Tue, 21 Jun 2011 17:46:39 +0200 Subject: [PATCH 49/66] use git util --- .../scm/repository/GitChangesetViewer.java | 18 +++++++----------- 1 file changed, 7 insertions(+), 11 deletions(-) diff --git a/plugins/scm-git-plugin/src/main/java/sonia/scm/repository/GitChangesetViewer.java b/plugins/scm-git-plugin/src/main/java/sonia/scm/repository/GitChangesetViewer.java index 951c3d9967..9e03615fd6 100644 --- a/plugins/scm-git-plugin/src/main/java/sonia/scm/repository/GitChangesetViewer.java +++ b/plugins/scm-git-plugin/src/main/java/sonia/scm/repository/GitChangesetViewer.java @@ -41,12 +41,9 @@ import org.eclipse.jgit.diff.DiffEntry; import org.eclipse.jgit.lib.ObjectId; import org.eclipse.jgit.lib.PersonIdent; import org.eclipse.jgit.lib.Ref; -import org.eclipse.jgit.lib.RepositoryCache; -import org.eclipse.jgit.lib.RepositoryCache.FileKey; import org.eclipse.jgit.revwalk.RevCommit; import org.eclipse.jgit.treewalk.EmptyTreeIterator; import org.eclipse.jgit.treewalk.TreeWalk; -import org.eclipse.jgit.util.FS; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -107,17 +104,20 @@ public class GitChangesetViewer implements ChangesetViewer ChangesetPagingResult changesets = null; File directory = handler.getDirectory(repository); org.eclipse.jgit.lib.Repository gr = null; + TreeWalk treeWalk = null; try { - gr = RepositoryCache.open(FileKey.lenient(directory, FS.DETECTED), true); + gr = GitUtil.open(directory); if (!gr.getAllRefs().isEmpty()) { Git git = new Git(gr); List changesetList = new ArrayList(); int counter = 0; - TreeWalk treeWalk = new TreeWalk(gr); + + treeWalk = new TreeWalk(gr); + Map tags = createTagMap(gr); for (RevCommit commit : git.log().call()) @@ -130,7 +130,6 @@ public class GitChangesetViewer implements ChangesetViewer counter++; } - treeWalk.release(); changesets = new ChangesetPagingResult(counter, changesetList); } } @@ -144,10 +143,8 @@ public class GitChangesetViewer implements ChangesetViewer } finally { - if (gr != null) - { - gr.close(); - } + GitUtil.release(treeWalk); + GitUtil.close(gr); } return changesets; @@ -203,7 +200,6 @@ public class GitChangesetViewer implements ChangesetViewer { String id = commit.getId().abbreviate(ID_LENGTH).name(); long date = GitUtil.getCommitTime(commit); - PersonIdent authorIndent = commit.getCommitterIdent(); Person author = new Person(authorIndent.getName(), authorIndent.getEmailAddress()); From 332f915f52e2829be53fde4ff5efec777afd3e3a Mon Sep 17 00:00:00 2001 From: Sebastian Sdorra Date: Wed, 22 Jun 2011 13:31:55 +0200 Subject: [PATCH 50/66] fix wrong commit message and commit date in git repository --- .../scm/repository/GitRepositoryBrowser.java | 50 +++++++++++-------- .../src/main/java/sonia/scm/util/Util.java | 44 ++++++++++++++++ 2 files changed, 73 insertions(+), 21 deletions(-) diff --git a/plugins/scm-git-plugin/src/main/java/sonia/scm/repository/GitRepositoryBrowser.java b/plugins/scm-git-plugin/src/main/java/sonia/scm/repository/GitRepositoryBrowser.java index 20d8ea97ca..b2ce205085 100644 --- a/plugins/scm-git-plugin/src/main/java/sonia/scm/repository/GitRepositoryBrowser.java +++ b/plugins/scm-git-plugin/src/main/java/sonia/scm/repository/GitRepositoryBrowser.java @@ -45,12 +45,16 @@ import org.eclipse.jgit.revwalk.RevCommit; import org.eclipse.jgit.revwalk.RevTree; import org.eclipse.jgit.revwalk.RevWalk; import org.eclipse.jgit.treewalk.TreeWalk; +import org.eclipse.jgit.treewalk.filter.AndTreeFilter; import org.eclipse.jgit.treewalk.filter.PathFilter; +import org.eclipse.jgit.treewalk.filter.TreeFilter; import org.eclipse.jgit.util.FS; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import sonia.scm.util.Util; + //~--- JDK imports ------------------------------------------------------------ import java.io.File; @@ -58,7 +62,6 @@ import java.io.IOException; import java.io.OutputStream; import java.util.ArrayList; -import java.util.Iterator; import java.util.List; /** @@ -192,7 +195,7 @@ public class GitRepositoryBrowser implements RepositoryBrowser while (treeWalk.next()) { - files.add(createFileObject(git, revId, treeWalk)); + files.add(createFileObject(repo, revId, treeWalk)); } result.setFiles(files); @@ -214,7 +217,8 @@ public class GitRepositoryBrowser implements RepositoryBrowser * * * - * @param git + * + * @param repo * @param revId * @param treeWalk * @@ -222,8 +226,8 @@ public class GitRepositoryBrowser implements RepositoryBrowser * * @throws IOException */ - private FileObject createFileObject(Git git, ObjectId revId, - TreeWalk treeWalk) + private FileObject createFileObject(org.eclipse.jgit.lib.Repository repo, + ObjectId revId, TreeWalk treeWalk) throws IOException { FileObject file = new FileObject(); @@ -232,12 +236,12 @@ public class GitRepositoryBrowser implements RepositoryBrowser file.setName(treeWalk.getNameString()); file.setPath(path); - ObjectLoader loader = git.getRepository().open(treeWalk.getObjectId(0)); + ObjectLoader loader = repo.open(treeWalk.getObjectId(0)); file.setDirectory(loader.getType() == Constants.OBJ_TREE); file.setLength(loader.getSize()); - RevCommit commit = getLatestCommit(git, revId, path); + RevCommit commit = getLatestCommit(repo, revId, path); if (commit != null) { @@ -258,36 +262,40 @@ public class GitRepositoryBrowser implements RepositoryBrowser * Method description * * - * @param git + * + * @param repo * @param revId * @param path * * @return */ - private RevCommit getLatestCommit(Git git, ObjectId revId, String path) + private RevCommit getLatestCommit(org.eclipse.jgit.lib.Repository repo, + ObjectId revId, String path) { - RevCommit commit = null; + RevCommit result = null; + RevWalk walk = null; try { - Iterable iterable = git.log().add(revId).addPath(path).call(); + walk = new RevWalk(repo); + walk.setTreeFilter(AndTreeFilter.create(PathFilter.create(path), + TreeFilter.ANY_DIFF)); - if (iterable != null) - { - Iterator it = iterable.iterator(); + RevCommit commit = walk.parseCommit(revId); - if ((it != null) && it.hasNext()) - { - commit = it.next(); - } - } + walk.markStart(commit); + result = Util.getFirst(walk); } catch (Exception ex) { - logger.error("could not fetch latest commit", ex); + logger.error("could not parse commit for file", ex); + } + finally + { + GitUtil.release(walk); } - return commit; + return result; } //~--- fields --------------------------------------------------------------- diff --git a/scm-core/src/main/java/sonia/scm/util/Util.java b/scm-core/src/main/java/sonia/scm/util/Util.java index 9ef1bcb039..14286adfb0 100644 --- a/scm-core/src/main/java/sonia/scm/util/Util.java +++ b/scm-core/src/main/java/sonia/scm/util/Util.java @@ -439,6 +439,50 @@ public class Util //~--- get methods ---------------------------------------------------------- + /** + * Method description + * + * + * @param iterable + * @param + * + * @return + * @since 1.5 + */ + public static T getFirst(Iterable iterable) + { + T result = null; + + if (iterable != null) + { + result = getFirst(iterable.iterator()); + } + + return result; + } + + /** + * Method description + * + * + * @param iterator + * @param + * + * @return + * @since 1.5 + */ + public static T getFirst(Iterator iterator) + { + T result = null; + + if ((iterator != null) && iterator.hasNext()) + { + result = iterator.next(); + } + + return result; + } + /** * Method description * From d86c1463b8034db2e15312c9a47c5714386e31b2 Mon Sep 17 00:00:00 2001 From: Sebastian Sdorra Date: Wed, 22 Jun 2011 13:33:29 +0200 Subject: [PATCH 51/66] fix possible NullPointerException --- .../scm/api/rest/resources/RepositoryResource.java | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/scm-webapp/src/main/java/sonia/scm/api/rest/resources/RepositoryResource.java b/scm-webapp/src/main/java/sonia/scm/api/rest/resources/RepositoryResource.java index a98ce7d90e..e657c3c908 100644 --- a/scm-webapp/src/main/java/sonia/scm/api/rest/resources/RepositoryResource.java +++ b/scm-webapp/src/main/java/sonia/scm/api/rest/resources/RepositoryResource.java @@ -230,8 +230,15 @@ public class RepositoryResource ChangesetPagingResult changesets = changesetViewer.getChangesets(start, limit); - callPreProcessors(changesets); - response = Response.ok(changesets).build(); + if (changesets != null) + { + callPreProcessors(changesets); + response = Response.ok(changesets).build(); + } + else + { + response = Response.ok().build(); + } } else { From 1d34c5b9c16f5b663cbbb28bd95ff4d24dd6c93e Mon Sep 17 00:00:00 2001 From: Sebastian Sdorra Date: Wed, 22 Jun 2011 17:51:31 +0200 Subject: [PATCH 52/66] release revwalk --- .../sonia/scm/repository/GitRepositoryBrowser.java | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/plugins/scm-git-plugin/src/main/java/sonia/scm/repository/GitRepositoryBrowser.java b/plugins/scm-git-plugin/src/main/java/sonia/scm/repository/GitRepositoryBrowser.java index b2ce205085..cb7cf7c70d 100644 --- a/plugins/scm-git-plugin/src/main/java/sonia/scm/repository/GitRepositoryBrowser.java +++ b/plugins/scm-git-plugin/src/main/java/sonia/scm/repository/GitRepositoryBrowser.java @@ -35,9 +35,6 @@ package sonia.scm.repository; //~--- non-JDK imports -------------------------------------------------------- -import org.eclipse.jgit.api.Git; -import org.eclipse.jgit.dircache.DirCache; -import org.eclipse.jgit.dircache.DirCacheIterator; import org.eclipse.jgit.lib.Constants; import org.eclipse.jgit.lib.ObjectId; import org.eclipse.jgit.lib.ObjectLoader; @@ -48,7 +45,6 @@ import org.eclipse.jgit.treewalk.TreeWalk; import org.eclipse.jgit.treewalk.filter.AndTreeFilter; import org.eclipse.jgit.treewalk.filter.PathFilter; import org.eclipse.jgit.treewalk.filter.TreeFilter; -import org.eclipse.jgit.util.FS; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -178,17 +174,16 @@ public class GitRepositoryBrowser implements RepositoryBrowser BrowserResult result = null; File directory = handler.getDirectory(repository); org.eclipse.jgit.lib.Repository repo = GitUtil.open(directory); - Git git = new Git(repo); + RevWalk revWalk = null; TreeWalk treeWalk = null; try { ObjectId revId = GitUtil.getRevisionId(repo, revision); - DirCache cache = new DirCache(directory, FS.DETECTED); treeWalk = new TreeWalk(repo); - treeWalk.addTree(new RevWalk(repo).parseTree(revId)); - treeWalk.addTree(new DirCacheIterator(cache)); + revWalk = new RevWalk(repo); + treeWalk.addTree(revWalk.parseTree(revId)); result = new BrowserResult(); List files = new ArrayList(); @@ -204,6 +199,7 @@ public class GitRepositoryBrowser implements RepositoryBrowser finally { GitUtil.close(repo); + GitUtil.release(revWalk); GitUtil.release(treeWalk); } From 42cd65de3bd5d0f0bab830fda223df2427745b19 Mon Sep 17 00:00:00 2001 From: Sebastian Sdorra Date: Wed, 22 Jun 2011 17:56:43 +0200 Subject: [PATCH 53/66] implement change directory --- .../scm/repository/GitRepositoryBrowser.java | 33 +++++++++++++++++-- 1 file changed, 31 insertions(+), 2 deletions(-) diff --git a/plugins/scm-git-plugin/src/main/java/sonia/scm/repository/GitRepositoryBrowser.java b/plugins/scm-git-plugin/src/main/java/sonia/scm/repository/GitRepositoryBrowser.java index cb7cf7c70d..e7719c6801 100644 --- a/plugins/scm-git-plugin/src/main/java/sonia/scm/repository/GitRepositoryBrowser.java +++ b/plugins/scm-git-plugin/src/main/java/sonia/scm/repository/GitRepositoryBrowser.java @@ -188,9 +188,38 @@ public class GitRepositoryBrowser implements RepositoryBrowser List files = new ArrayList(); - while (treeWalk.next()) + if (Util.isEmpty(path)) { - files.add(createFileObject(repo, revId, treeWalk)); + while (treeWalk.next()) + { + files.add(createFileObject(repo, revId, treeWalk)); + } + } + else + { + String[] parts = path.split("/"); + int current = 0; + int limit = parts.length; + + while (treeWalk.next()) + { + String name = treeWalk.getNameString(); + + if (current >= limit) + { + String p = treeWalk.getPathString(); + + if (p.split("/").length > limit) + { + files.add(createFileObject(repo, revId, treeWalk)); + } + } + else if (name.equalsIgnoreCase(parts[current])) + { + current++; + treeWalk.enterSubtree(); + } + } } result.setFiles(files); From 14f13703e145daf77068fd1f41dce50e6d100bfb Mon Sep 17 00:00:00 2001 From: Sebastian Sdorra Date: Wed, 22 Jun 2011 17:58:47 +0200 Subject: [PATCH 54/66] fix get content from subdirectory --- .../src/main/java/sonia/scm/repository/GitRepositoryBrowser.java | 1 + 1 file changed, 1 insertion(+) diff --git a/plugins/scm-git-plugin/src/main/java/sonia/scm/repository/GitRepositoryBrowser.java b/plugins/scm-git-plugin/src/main/java/sonia/scm/repository/GitRepositoryBrowser.java index e7719c6801..0c4aa82c16 100644 --- a/plugins/scm-git-plugin/src/main/java/sonia/scm/repository/GitRepositoryBrowser.java +++ b/plugins/scm-git-plugin/src/main/java/sonia/scm/repository/GitRepositoryBrowser.java @@ -113,6 +113,7 @@ public class GitRepositoryBrowser implements RepositoryBrowser try { treeWalk = new TreeWalk(repo); + treeWalk.setRecursive(Util.nonNull(path).contains("/")); ObjectId revId = GitUtil.getRevisionId(repo, revision); From 2a8ba7c70ca82f45a1ea958a9e34cc0ada325e31 Mon Sep 17 00:00:00 2001 From: Sebastian Sdorra Date: Wed, 22 Jun 2011 18:04:25 +0200 Subject: [PATCH 55/66] improve performance --- .../scm/repository/GitRepositoryBrowser.java | 22 +++++++++++-------- 1 file changed, 13 insertions(+), 9 deletions(-) diff --git a/plugins/scm-git-plugin/src/main/java/sonia/scm/repository/GitRepositoryBrowser.java b/plugins/scm-git-plugin/src/main/java/sonia/scm/repository/GitRepositoryBrowser.java index 0c4aa82c16..6969d9b136 100644 --- a/plugins/scm-git-plugin/src/main/java/sonia/scm/repository/GitRepositoryBrowser.java +++ b/plugins/scm-git-plugin/src/main/java/sonia/scm/repository/GitRepositoryBrowser.java @@ -267,16 +267,20 @@ public class GitRepositoryBrowser implements RepositoryBrowser file.setDirectory(loader.getType() == Constants.OBJ_TREE); file.setLength(loader.getSize()); - RevCommit commit = getLatestCommit(repo, revId, path); + // don't show message and date for directories to improve performance + if (!file.isDirectory()) + { + RevCommit commit = getLatestCommit(repo, revId, path); - if (commit != null) - { - file.setLastModified(GitUtil.getCommitTime(commit)); - file.setDescription(commit.getShortMessage()); - } - else if (logger.isWarnEnabled()) - { - logger.warn("could not find latest commit for {} on {}", path, revId); + if (commit != null) + { + file.setLastModified(GitUtil.getCommitTime(commit)); + file.setDescription(commit.getShortMessage()); + } + else if (logger.isWarnEnabled()) + { + logger.warn("could not find latest commit for {} on {}", path, revId); + } } return file; From 854fc6bb032f05461a76ce5df62ddb84eafb0d0d Mon Sep 17 00:00:00 2001 From: Sebastian Sdorra Date: Wed, 22 Jun 2011 18:10:20 +0200 Subject: [PATCH 56/66] added repository name and revision to the bottom of the repository browser --- .../repository/sonia.repository.repositorybrowser.js | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/scm-webapp/src/main/webapp/resources/js/repository/sonia.repository.repositorybrowser.js b/scm-webapp/src/main/webapp/resources/js/repository/sonia.repository.repositorybrowser.js index 5ca2e00502..9fa09d8e45 100644 --- a/scm-webapp/src/main/webapp/resources/js/repository/sonia.repository.repositorybrowser.js +++ b/scm-webapp/src/main/webapp/resources/js/repository/sonia.repository.repositorybrowser.js @@ -106,7 +106,17 @@ Sonia.repository.RepositoryBrowser = Ext.extend(Ext.grid.GridPanel, { }] }); + var bbar = [ + '->', + this.repository.name + ]; + + if ( this.revision != null ){ + bbar.push(': ', this.revision); + } + var config = { + bbar: bbar, autoExpandColumn: 'description', title: String.format(this.repositoryBrowserTitleText, this.repository.name), store: browserStore, From 5537c0317349460fe81dd6556a59884fd6dcac28 Mon Sep 17 00:00:00 2001 From: Sebastian Sdorra Date: Wed, 22 Jun 2011 19:10:56 +0200 Subject: [PATCH 57/66] added clickpath to repository browser --- .../sonia.repository.repositorybrowser.js | 37 +++++++++++++++++-- 1 file changed, 34 insertions(+), 3 deletions(-) diff --git a/scm-webapp/src/main/webapp/resources/js/repository/sonia.repository.repositorybrowser.js b/scm-webapp/src/main/webapp/resources/js/repository/sonia.repository.repositorybrowser.js index 9fa09d8e45..d33be53ef6 100644 --- a/scm-webapp/src/main/webapp/resources/js/repository/sonia.repository.repositorybrowser.js +++ b/scm-webapp/src/main/webapp/resources/js/repository/sonia.repository.repositorybrowser.js @@ -106,17 +106,20 @@ Sonia.repository.RepositoryBrowser = Ext.extend(Ext.grid.GridPanel, { }] }); - var bbar = [ + var bItems = [ '->', this.repository.name ]; if ( this.revision != null ){ - bbar.push(': ', this.revision); + bItems.push(': ', this.revision); } var config = { - bbar: bbar, + bbar: { + id: 'bbar-' + this.repository.id, + items: bItems + }, autoExpandColumn: 'description', title: String.format(this.repositoryBrowserTitleText, this.repository.name), store: browserStore, @@ -237,6 +240,34 @@ Sonia.repository.RepositoryBrowser = Ext.extend(Ext.grid.GridPanel, { path: path } }); + + this.renderPath(path); + }, + + renderPath: function(path){ + var bbar = Ext.getCmp('bbar-' + this.repository.id); + bbar.removeAll(); + + var parts = path.split('/'); + var items = []; + var currentPath = ''; + for (var i=0; i', this.repository.name); + if ( this.revision != null ){ + items.push(':', this.revision); + } + + bbar.add(items); + bbar.doLayout(); }, renderName: function(name, p, record){ From 03546a24e0ea2d23a579539f3df7c8fcbbffbbce Mon Sep 17 00:00:00 2001 From: Sebastian Sdorra Date: Thu, 23 Jun 2011 19:45:09 +0200 Subject: [PATCH 58/66] added root folder to clickpath --- .../sonia.repository.repositorybrowser.js | 30 ++++++++++++------- 1 file changed, 19 insertions(+), 11 deletions(-) diff --git a/scm-webapp/src/main/webapp/resources/js/repository/sonia.repository.repositorybrowser.js b/scm-webapp/src/main/webapp/resources/js/repository/sonia.repository.repositorybrowser.js index d33be53ef6..6fdc211d29 100644 --- a/scm-webapp/src/main/webapp/resources/js/repository/sonia.repository.repositorybrowser.js +++ b/scm-webapp/src/main/webapp/resources/js/repository/sonia.repository.repositorybrowser.js @@ -107,6 +107,7 @@ Sonia.repository.RepositoryBrowser = Ext.extend(Ext.grid.GridPanel, { }); var bItems = [ + this.createFolderButton('', ''), '->', this.repository.name ]; @@ -241,24 +242,31 @@ Sonia.repository.RepositoryBrowser = Ext.extend(Ext.grid.GridPanel, { } }); - this.renderPath(path); + this.renderClickPath(path); }, - renderPath: function(path){ + createFolderButton: function(path, name){ + return { + xtype: 'button', + icon: this.iconFolder, + text: name + '/', + handler: this.changeDirectory.createDelegate(this, [path]) + }; + }, + + renderClickPath: function(path){ var bbar = Ext.getCmp('bbar-' + this.repository.id); bbar.removeAll(); var parts = path.split('/'); - var items = []; var currentPath = ''; - for (var i=0; i', this.repository.name); From f37db06719ff2712c2189bcb73db990a430ea5c0 Mon Sep 17 00:00:00 2001 From: Sebastian Sdorra Date: Thu, 23 Jun 2011 21:37:09 +0200 Subject: [PATCH 59/66] added information toolbar to file panel --- .../sonia.repository.repositorybrowser.js | 24 +++++++++++-------- 1 file changed, 14 insertions(+), 10 deletions(-) diff --git a/scm-webapp/src/main/webapp/resources/js/repository/sonia.repository.repositorybrowser.js b/scm-webapp/src/main/webapp/resources/js/repository/sonia.repository.repositorybrowser.js index 6fdc211d29..2172f1848e 100644 --- a/scm-webapp/src/main/webapp/resources/js/repository/sonia.repository.repositorybrowser.js +++ b/scm-webapp/src/main/webapp/resources/js/repository/sonia.repository.repositorybrowser.js @@ -106,15 +106,8 @@ Sonia.repository.RepositoryBrowser = Ext.extend(Ext.grid.GridPanel, { }] }); - var bItems = [ - this.createFolderButton('', ''), - '->', - this.repository.name - ]; - - if ( this.revision != null ){ - bItems.push(': ', this.revision); - } + var bItems = [this.createFolderButton('', '')]; + this.appendRepositoryProperties(bItems); var config = { bbar: { @@ -204,6 +197,13 @@ Sonia.repository.RepositoryBrowser = Ext.extend(Ext.grid.GridPanel, { return ext; }, + appendRepositoryProperties: function(bar){ + bar.push('->',this.repository.name); + if ( this.revision != null ){ + bar.push(': ', this.revision); + } + }, + openFile: function(path){ if ( debug ){ console.debug( 'open file: ' + path ); @@ -216,6 +216,9 @@ Sonia.repository.RepositoryBrowser = Ext.extend(Ext.grid.GridPanel, { url += "&revision=" + this.revision; } + var bar = [path]; + this.appendRepositoryProperties(bar); + main.addTab({ id: this.repository.id + "-b-" + path, contentUrl: url, @@ -223,7 +226,8 @@ Sonia.repository.RepositoryBrowser = Ext.extend(Ext.grid.GridPanel, { title: this.getName(path), closable: true, autoScroll: true, - syntax: ext + syntax: ext, + bbar: bar }); }, From 67a8c75e65a59b89dac269eb65820e9b8c4b9761 Mon Sep 17 00:00:00 2001 From: Sebastian Sdorra Date: Thu, 23 Jun 2011 21:41:31 +0200 Subject: [PATCH 60/66] fix bug with multiple clickpath toolbar from same repository --- .../repository/sonia.repository.repositorybrowser.js | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/scm-webapp/src/main/webapp/resources/js/repository/sonia.repository.repositorybrowser.js b/scm-webapp/src/main/webapp/resources/js/repository/sonia.repository.repositorybrowser.js index 2172f1848e..849525f8ff 100644 --- a/scm-webapp/src/main/webapp/resources/js/repository/sonia.repository.repositorybrowser.js +++ b/scm-webapp/src/main/webapp/resources/js/repository/sonia.repository.repositorybrowser.js @@ -106,14 +106,11 @@ Sonia.repository.RepositoryBrowser = Ext.extend(Ext.grid.GridPanel, { }] }); - var bItems = [this.createFolderButton('', '')]; - this.appendRepositoryProperties(bItems); + var bar = [this.createFolderButton('', '')]; + this.appendRepositoryProperties(bar); var config = { - bbar: { - id: 'bbar-' + this.repository.id, - items: bItems - }, + bbar: bar, autoExpandColumn: 'description', title: String.format(this.repositoryBrowserTitleText, this.repository.name), store: browserStore, @@ -259,7 +256,7 @@ Sonia.repository.RepositoryBrowser = Ext.extend(Ext.grid.GridPanel, { }, renderClickPath: function(path){ - var bbar = Ext.getCmp('bbar-' + this.repository.id); + var bbar = this.getBottomToolbar(); bbar.removeAll(); var parts = path.split('/'); From aba48fe886f56a9db60d6a3bf2e6dd9daf62252d Mon Sep 17 00:00:00 2001 From: Sebastian Sdorra Date: Fri, 24 Jun 2011 17:03:16 +0200 Subject: [PATCH 61/66] improve infopanels --- .../sonia.repository.extendedinfopanel.js | 35 ++++++++++++++----- .../repository/sonia.repository.infopanel.js | 5 ++- .../sonia.repository.repositorybrowser.js | 2 +- 3 files changed, 30 insertions(+), 12 deletions(-) diff --git a/scm-webapp/src/main/webapp/resources/js/repository/sonia.repository.extendedinfopanel.js b/scm-webapp/src/main/webapp/resources/js/repository/sonia.repository.extendedinfopanel.js index af39536d8c..1e61c0981a 100644 --- a/scm-webapp/src/main/webapp/resources/js/repository/sonia.repository.extendedinfopanel.js +++ b/scm-webapp/src/main/webapp/resources/js/repository/sonia.repository.extendedinfopanel.js @@ -40,7 +40,10 @@ Sonia.repository.ExtendedInfoPanel = Ext.extend(Sonia.repository.InfoPanel,{ checkoutText: 'Checkout: ', // TODO i18n - repositoryBrowserText: 'RepositoryBrowser', + repositoryBrowserText: 'Source', + + enableRepositoryBrowser: true, + enableChangesetViewer: true, modifyDefaultConfig: function(config){ var items = config.items; @@ -56,18 +59,34 @@ Sonia.repository.ExtendedInfoPanel = Ext.extend(Sonia.repository.InfoPanel,{ this.checkoutTemplate, this.getRepositoryUrlWithUsername() ) - }, - this.createSpacer(), - this.createChangesetViewerLink(), - this.createSpacer(), - this.createRepositoryBrowserLink() - ); + },this.createSpacer()); + + var box = { + xtype: 'panel', + colspan: 2, + layout: 'column', + items: [ + this.createChangesetViewerLink(),{ + xtyle: 'box', + html: ', ', + width: 8 + }, this.createRepositoryBrowserLink() + ] + } + + items.push(box); + + if ( this.enableChangesetViewer ){ + // items.push(this.createChangesetViewerLink()); + } + if ( this.enableRepositoryBrowser ){ + // items.push(this.createRepositoryBrowserLink()); + } }, createRepositoryBrowserLink: function(){ return { xtype: 'link', - colspan: 2, text: this.repositoryBrowserText, handler: this.openRepositoryBrowser, scope: this diff --git a/scm-webapp/src/main/webapp/resources/js/repository/sonia.repository.infopanel.js b/scm-webapp/src/main/webapp/resources/js/repository/sonia.repository.infopanel.js index 85663eb1b4..e36a138043 100644 --- a/scm-webapp/src/main/webapp/resources/js/repository/sonia.repository.infopanel.js +++ b/scm-webapp/src/main/webapp/resources/js/repository/sonia.repository.infopanel.js @@ -43,8 +43,8 @@ Sonia.repository.InfoPanel = Ext.extend(Ext.Panel, { typeText: 'Type: ', contactText: 'Contact: ', urlText: 'Url: ', - changesetViewerText: 'ChangesetViewer', - changesetViewerTitleText: 'ChangesetViewer {0}', + changesetViewerText: 'Commits', + changesetViewerTitleText: 'Commits {0}', initComponent: function(){ @@ -141,7 +141,6 @@ Sonia.repository.InfoPanel = Ext.extend(Ext.Panel, { createChangesetViewerLink: function(){ return { xtype: 'link', - colspan: 2, text: this.changesetViewerText, handler: this.openChangesetViewer, scope: this diff --git a/scm-webapp/src/main/webapp/resources/js/repository/sonia.repository.repositorybrowser.js b/scm-webapp/src/main/webapp/resources/js/repository/sonia.repository.repositorybrowser.js index 849525f8ff..26480d1886 100644 --- a/scm-webapp/src/main/webapp/resources/js/repository/sonia.repository.repositorybrowser.js +++ b/scm-webapp/src/main/webapp/resources/js/repository/sonia.repository.repositorybrowser.js @@ -35,7 +35,7 @@ Sonia.repository.RepositoryBrowser = Ext.extend(Ext.grid.GridPanel, { revision: null, // TODO i18n - repositoryBrowserTitleText: 'RepositoryBrowser: {0}', + repositoryBrowserTitleText: 'Source: {0}', iconFolder: 'resources/images/folder.gif', iconDocument: 'resources/images/document.gif', templateIcon: '{1}', From bade42bec49197594a27dc8da463d61862489847 Mon Sep 17 00:00:00 2001 From: Sebastian Sdorra Date: Fri, 24 Jun 2011 17:06:36 +0200 Subject: [PATCH 62/66] implement support for repositorybrowser and changesetviewer enable switches --- .../sonia.repository.extendedinfopanel.js | 31 ++++++++++--------- 1 file changed, 16 insertions(+), 15 deletions(-) diff --git a/scm-webapp/src/main/webapp/resources/js/repository/sonia.repository.extendedinfopanel.js b/scm-webapp/src/main/webapp/resources/js/repository/sonia.repository.extendedinfopanel.js index 1e61c0981a..399d08cfdd 100644 --- a/scm-webapp/src/main/webapp/resources/js/repository/sonia.repository.extendedinfopanel.js +++ b/scm-webapp/src/main/webapp/resources/js/repository/sonia.repository.extendedinfopanel.js @@ -61,27 +61,28 @@ Sonia.repository.ExtendedInfoPanel = Ext.extend(Sonia.repository.InfoPanel,{ ) },this.createSpacer()); - var box = { - xtype: 'panel', - colspan: 2, - layout: 'column', - items: [ - this.createChangesetViewerLink(),{ + var box = []; + if ( this.enableChangesetViewer ){ + box.push(this.createChangesetViewerLink()); + if (this.enableRepositoryBrowser){ + box.push({ xtyle: 'box', html: ', ', width: 8 - }, this.createRepositoryBrowserLink() - ] + }); + } } - items.push(box); + if (this.enableRepositoryBrowser){ + box.push(this.createRepositoryBrowserLink()); + } - if ( this.enableChangesetViewer ){ - // items.push(this.createChangesetViewerLink()); - } - if ( this.enableRepositoryBrowser ){ - // items.push(this.createRepositoryBrowserLink()); - } + items.push({ + xtype: 'panel', + colspan: 2, + layout: 'column', + items: box + }); }, createRepositoryBrowserLink: function(){ From 462911edcfd2fa81a81f55e40b3de3114d2ca97a Mon Sep 17 00:00:00 2001 From: Sebastian Sdorra Date: Fri, 24 Jun 2011 17:13:54 +0200 Subject: [PATCH 63/66] accent commit and source link --- .../js/repository/sonia.repository.extendedinfopanel.js | 1 + .../resources/js/repository/sonia.repository.infopanel.js | 1 + .../src/main/webapp/resources/js/util/sonia.util.link.js | 8 +++++++- 3 files changed, 9 insertions(+), 1 deletion(-) diff --git a/scm-webapp/src/main/webapp/resources/js/repository/sonia.repository.extendedinfopanel.js b/scm-webapp/src/main/webapp/resources/js/repository/sonia.repository.extendedinfopanel.js index 399d08cfdd..0e67d4862a 100644 --- a/scm-webapp/src/main/webapp/resources/js/repository/sonia.repository.extendedinfopanel.js +++ b/scm-webapp/src/main/webapp/resources/js/repository/sonia.repository.extendedinfopanel.js @@ -88,6 +88,7 @@ Sonia.repository.ExtendedInfoPanel = Ext.extend(Sonia.repository.InfoPanel,{ createRepositoryBrowserLink: function(){ return { xtype: 'link', + style: 'font-weight: bold', text: this.repositoryBrowserText, handler: this.openRepositoryBrowser, scope: this diff --git a/scm-webapp/src/main/webapp/resources/js/repository/sonia.repository.infopanel.js b/scm-webapp/src/main/webapp/resources/js/repository/sonia.repository.infopanel.js index e36a138043..232c861375 100644 --- a/scm-webapp/src/main/webapp/resources/js/repository/sonia.repository.infopanel.js +++ b/scm-webapp/src/main/webapp/resources/js/repository/sonia.repository.infopanel.js @@ -141,6 +141,7 @@ Sonia.repository.InfoPanel = Ext.extend(Ext.Panel, { createChangesetViewerLink: function(){ return { xtype: 'link', + style: 'font-weight: bold', text: this.changesetViewerText, handler: this.openChangesetViewer, scope: this diff --git a/scm-webapp/src/main/webapp/resources/js/util/sonia.util.link.js b/scm-webapp/src/main/webapp/resources/js/util/sonia.util.link.js index ef1f82ac13..e9a66e323c 100644 --- a/scm-webapp/src/main/webapp/resources/js/util/sonia.util.link.js +++ b/scm-webapp/src/main/webapp/resources/js/util/sonia.util.link.js @@ -37,7 +37,13 @@ Sonia.util.Link = Ext.extend(Ext.BoxComponent, { constructor: function(config) { config = config || {}; config.xtype = 'box'; - config.autoEl = { tag: 'a', html: config.text, href: '#' }; + config.autoEl = { + tag: 'a', + html: config.text, + href: '#', + style: config.style, + 'class': config['class'] + }; config.listeners = { render: function(c) { c.getEl().on('click', function(){ From a2177fa36b831dc8128949383b3aa91cc761bfec Mon Sep 17 00:00:00 2001 From: Sebastian Sdorra Date: Fri, 24 Jun 2011 17:26:17 +0200 Subject: [PATCH 64/66] added german locale for new labels --- scm-webapp/src/main/webapp/resources/js/i18n/de.js | 14 +++++++++++--- .../sonia.repository.extendedinfopanel.js | 1 - .../sonia.repository.repositorybrowser.js | 2 +- 3 files changed, 12 insertions(+), 5 deletions(-) diff --git a/scm-webapp/src/main/webapp/resources/js/i18n/de.js b/scm-webapp/src/main/webapp/resources/js/i18n/de.js index 51ffdcde20..58b513b4d6 100644 --- a/scm-webapp/src/main/webapp/resources/js/i18n/de.js +++ b/scm-webapp/src/main/webapp/resources/js/i18n/de.js @@ -210,8 +210,8 @@ if (Sonia.repository.InfoPanel){ contactText: 'Kontakt: ', urlText: 'Url: ', // german ?? - changesetViewerText: 'ChangesetViewer', - changesetViewerTitleText: 'ChangesetViewer {0}' + changesetViewerText: 'Commits', + changesetViewerTitleText: 'Commits: {0}' }); } @@ -220,11 +220,19 @@ if (Sonia.repository.ExtendedInfoPanel){ Ext.override(Sonia.repository.ExtendedInfoPanel, { // german ?? - checkoutText: 'Checkout: ' + checkoutText: 'Checkout: ', + repositoryBrowserText: 'Source' }); } +if (Sonia.repository.RepositoryBrowser){ + Ext.override(Sonia.repository.RepositoryBrowser, { + // german ?? + repositoryBrowserTitleText: 'Source: {0}' + }); +} + // sonia.config.js if (Sonia.config.ScmConfigPanel){ diff --git a/scm-webapp/src/main/webapp/resources/js/repository/sonia.repository.extendedinfopanel.js b/scm-webapp/src/main/webapp/resources/js/repository/sonia.repository.extendedinfopanel.js index 0e67d4862a..c07bf51789 100644 --- a/scm-webapp/src/main/webapp/resources/js/repository/sonia.repository.extendedinfopanel.js +++ b/scm-webapp/src/main/webapp/resources/js/repository/sonia.repository.extendedinfopanel.js @@ -39,7 +39,6 @@ Sonia.repository.ExtendedInfoPanel = Ext.extend(Sonia.repository.InfoPanel,{ // text checkoutText: 'Checkout: ', - // TODO i18n repositoryBrowserText: 'Source', enableRepositoryBrowser: true, diff --git a/scm-webapp/src/main/webapp/resources/js/repository/sonia.repository.repositorybrowser.js b/scm-webapp/src/main/webapp/resources/js/repository/sonia.repository.repositorybrowser.js index 26480d1886..3129460b05 100644 --- a/scm-webapp/src/main/webapp/resources/js/repository/sonia.repository.repositorybrowser.js +++ b/scm-webapp/src/main/webapp/resources/js/repository/sonia.repository.repositorybrowser.js @@ -34,8 +34,8 @@ Sonia.repository.RepositoryBrowser = Ext.extend(Ext.grid.GridPanel, { repository: null, revision: null, - // TODO i18n repositoryBrowserTitleText: 'Source: {0}', + iconFolder: 'resources/images/folder.gif', iconDocument: 'resources/images/document.gif', templateIcon: '{1}', From 304e2710f5a63f9c7f7ae4949c872f4389baed67 Mon Sep 17 00:00:00 2001 From: Sebastian Sdorra Date: Thu, 30 Jun 2011 09:39:20 +0200 Subject: [PATCH 65/66] update jgit to version 1.0.0.201106090707-r --- plugins/scm-git-plugin/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/scm-git-plugin/pom.xml b/plugins/scm-git-plugin/pom.xml index 81f23726ef..a3302db163 100644 --- a/plugins/scm-git-plugin/pom.xml +++ b/plugins/scm-git-plugin/pom.xml @@ -63,7 +63,7 @@ - 0.12.1 + 1.0.0.201106090707-r From 3ea6b9114a89a8749d37d690a42e39c6630620d9 Mon Sep 17 00:00:00 2001 From: Sebastian Sdorra Date: Fri, 1 Jul 2011 12:04:05 +0200 Subject: [PATCH 66/66] close branch repository-browser