/* * Copyright 2011 gitblit.com. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.gitblit.wicket.pages; import java.text.MessageFormat; import java.util.HashMap; import java.util.Map; import org.apache.wicket.Component; import org.apache.wicket.PageParameters; import org.apache.wicket.RedirectException; import org.apache.wicket.markup.html.basic.Label; import org.apache.wicket.markup.html.image.Image; import org.apache.wicket.markup.html.link.BookmarkablePageLink; import org.apache.wicket.markup.html.link.ExternalLink; import org.eclipse.jgit.lib.Repository; import org.eclipse.jgit.revwalk.RevCommit; import com.gitblit.Keys; import com.gitblit.servlet.RawServlet; import com.gitblit.utils.JGitUtils; import com.gitblit.utils.StringUtils; import com.gitblit.wicket.CacheControl; import com.gitblit.wicket.CacheControl.LastModified; import com.gitblit.wicket.ExternalImage; import com.gitblit.wicket.MarkupProcessor; import com.gitblit.wicket.WicketUtils; import com.gitblit.wicket.panels.CommitHeaderPanel; import com.gitblit.wicket.panels.PathBreadcrumbsPanel; @CacheControl(LastModified.BOOT) public class BlobPage extends RepositoryPage { protected String fileExtension; public BlobPage(PageParameters params) { super(params); Repository r = getRepository(); final String blobPath = WicketUtils.getPath(params); String [] encodings = getEncodings(); if (StringUtils.isEmpty(objectId) && StringUtils.isEmpty(blobPath)) { throw new RedirectException(TreePage.class, WicketUtils.newRepositoryParameter(repositoryName)); } if (StringUtils.isEmpty(blobPath)) { // blob by objectid add(new BookmarkablePageLink("blameLink", BlamePage.class, WicketUtils.newPathParameter(repositoryName, objectId, blobPath)) .setEnabled(false)); add(new BookmarkablePageLink("historyLink", HistoryPage.class).setEnabled(false)); String rawUrl = RawServlet.asLink(getContextUrl(), repositoryName, objectId, blobPath); add(new ExternalLink("rawLink", rawUrl)); add(new CommitHeaderPanel("commitHeader", objectId)); add(new PathBreadcrumbsPanel("breadcrumbs", repositoryName, blobPath, objectId)); Component c = new Label("blobText", JGitUtils.getStringContent(r, objectId, encodings)); WicketUtils.setCssClass(c, "plainprint"); add(c); } else { // standard blob view String extension = null; if (blobPath.lastIndexOf('.') > -1) { extension = blobPath.substring(blobPath.lastIndexOf('.') + 1).toLowerCase(); } // see if we should redirect to the doc page MarkupProcessor processor = new MarkupProcessor(app().settings(), app().xssFilter()); for (String ext : processor.getMarkupExtensions()) { if (ext.equals(extension)) { setResponsePage(DocPage.class, params); return; } } RevCommit commit = getCommit(); // blob page links add(new BookmarkablePageLink("blameLink", BlamePage.class, WicketUtils.newPathParameter(repositoryName, objectId, blobPath))); add(new BookmarkablePageLink("historyLink", HistoryPage.class, WicketUtils.newPathParameter(repositoryName, objectId, blobPath))); String rawUrl = RawServlet.asLink(getContextUrl(), repositoryName, objectId, blobPath); add(new ExternalLink("rawLink", rawUrl)); add(new CommitHeaderPanel("commitHeader", repositoryName, commit)); add(new PathBreadcrumbsPanel("breadcrumbs", repositoryName, blobPath, objectId)); // Map the extensions to types Map map = new HashMap(); for (String ext : app().settings().getStrings(Keys.web.prettyPrintExtensions)) { map.put(ext.toLowerCase(), 1); } for (String ext : app().settings().getStrings(Keys.web.imageExtensions)) { map.put(ext.toLowerCase(), 2); } for (String ext : app().settings().getStrings(Keys.web.binaryExtensions)) { map.put(ext.toLowerCase(), 3); } if (extension != null) { int type = 0; if (map.containsKey(extension)) { type = map.get(extension); } switch (type) { case 2: // image blobs add(new Label("blobText").setVisible(false)); add(new ExternalImage("blobImage", rawUrl)); break; case 3: // binary blobs add(new Label("blobText", "Binary File")); add(new Image("blobImage").setVisible(false)); break; default: // plain text String source = JGitUtils.getStringContent(r, commit.getTree(), blobPath, encodings); String table; if (source == null) { table = missingBlob(blobPath, commit); } else { table = generateSourceView(source, extension, type == 1); addBottomScriptInline("jQuery(prettyPrint);"); } add(new Label("blobText", table).setEscapeModelStrings(false)); add(new Image("blobImage").setVisible(false)); fileExtension = extension; } } else { // plain text String source = JGitUtils.getStringContent(r, commit.getTree(), blobPath, encodings); String table; if (source == null) { table = missingBlob(blobPath, commit); } else { table = generateSourceView(source, null, false); addBottomScriptInline("jQuery(prettyPrint);"); } add(new Label("blobText", table).setEscapeModelStrings(false)); add(new Image("blobImage").setVisible(false)); } } } protected String missingBlob(String blobPath, RevCommit commit) { StringBuilder sb = new StringBuilder(); sb.append("
"); String pattern = getString("gb.doesNotExistInTree").replace("{0}", "{0}").replace("{1}", "{1}"); sb.append(MessageFormat.format(pattern, blobPath, commit.getTree().getId().getName())); sb.append("
"); return sb.toString(); } protected String generateSourceView(String source, String extension, boolean prettyPrint) { String [] lines = source.split("\n"); StringBuilder sb = new StringBuilder(); sb.append(""); sb.append(""); // nums column sb.append(""); sb.append(""); sb.append(""); sb.append(""); sb.append(""); sb.append("
"); sb.append("
");
		String numPattern = "{0}\n";
		for (int i = 0; i < lines.length; i++) {
			sb.append(MessageFormat.format(numPattern, "" + (i + 1)));
		}
		sb.append("
"); sb.append(""); sb.append("
"); sb.append("
"); if (prettyPrint) { sb.append("
");
		} else {
			sb.append("
");
		}
		final int tabLength = app().settings().getInteger(Keys.web.tabLength, 4);
		lines = StringUtils.escapeForHtml(source, true, tabLength).split("\n");

		sb.append("");

		String linePattern = "";
		for (int i = 0; i < lines.length; i++) {
			String line = lines[i].replace('\r', ' ');
			String cssClass = (i % 2 == 0) ? "even" : "odd";
			if (StringUtils.isEmpty(line.trim())) {
				line = " ";
			}
			sb.append(MessageFormat.format(linePattern, cssClass, line, "" + (i + 1)));
		}
		sb.append("
{1}
\r
"); sb.append("
"); sb.append("
"); sb.append("
"); sb.append(""); return sb.toString(); } @Override protected String getPageName() { return getString("gb.view"); } @Override protected boolean isCommitPage() { return true; } @Override protected Class getRepoNavPageClass() { return TreePage.class; } }