/* * Copyright 2000-2012 JetBrains s.r.o. * * 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 jetbrains.buildServer.usageStatistics.impl.providers; import java.io.BufferedReader; import java.io.File; import java.io.IOException; import java.io.InputStreamReader; import java.util.*; import java.util.regex.Pattern; import java.util.regex.PatternSyntaxException; import java.util.zip.ZipEntry; import java.util.zip.ZipFile; import javax.servlet.http.HttpServletRequest; import jetbrains.buildServer.plugins.bean.ServerPluginInfo; import jetbrains.buildServer.serverSide.SBuildServer; import jetbrains.buildServer.serverSide.ServerPaths; import jetbrains.buildServer.usageStatistics.presentation.UsageStatisticsGroupPosition; import jetbrains.buildServer.users.SUser; import jetbrains.buildServer.util.Dates; import jetbrains.buildServer.util.positioning.PositionAware; import jetbrains.buildServer.web.openapi.PagePlaces; import jetbrains.buildServer.web.openapi.PlaceId; import jetbrains.buildServer.web.openapi.PluginDescriptor; import jetbrains.buildServer.web.openapi.SimplePageExtension; import jetbrains.buildServer.web.util.SessionUser; import jetbrains.buildServer.web.util.WebUtil; import org.apache.log4j.Logger; import org.jetbrains.annotations.NotNull; public class WebPagesUsageStatisticsProvider extends BaseToolUsersUsageStatisticsProvider implements WebUsersProvider { @NotNull private static final Logger LOG = Logger.getLogger(WebPagesUsageStatisticsProvider.class); @NotNull private final List myPathPatterns = new ArrayList(); @NotNull private final ServerPluginInfo myPluginDescriptor; public WebPagesUsageStatisticsProvider(@NotNull final SBuildServer server, @NotNull final ServerPaths serverPaths, @NotNull final PagePlaces pagePlaces, @NotNull final ServerPluginInfo pluginDescriptor) { super(server, serverPaths, new LinkedHashMap() {{ put(Dates.ONE_WEEK, "Week"); put(30 * Dates.ONE_DAY, "Month"); }}); myPluginDescriptor = pluginDescriptor; registerPageExtension(pagePlaces, pluginDescriptor); } @NotNull @Override protected PositionAware getGroupPosition() { return UsageStatisticsGroupPosition.WEB_PAGES_USAGE; } public void setConfigFilePath(@NotNull final String configFilePath) { readWebPagePatterns(configFilePath); } @NotNull public Set getWebUsers(final long fromTimestamp) { return getUsers(fromTimestamp); } public void processGetRequest(@NotNull final HttpServletRequest request) { SUser user = null; try { user = SessionUser.getUser(request); } catch (final Exception ignore) {} // TW-18334 if (user == null) return; String path = WebUtil.getPathFromUrl(WebUtil.getPathWithoutContext(request)); if (!path.toLowerCase().endsWith(".html")) return; final String tab = request.getParameter("tab"); if (tab != null) { path += "?tab=" + tab; } addUsage(path, user.getId()); } @NotNull @Override protected String getExternalId() { return "webPagesUsage"; } @NotNull @Override protected String getToolName() { return "page"; } @NotNull @Override protected String getToolIdName() { return "path"; } @Override protected boolean publishToolUsages(@NotNull final String path) { for (final Pattern pathPattern : myPathPatterns) { if (pathPattern.matcher(path).matches()) { return true; } } return false; } @NotNull @Override protected String getValueTooltip() { return "User count (% of web users)"; } private void registerPageExtension(@NotNull final PagePlaces pagePlaces, @NotNull final PluginDescriptor pluginDescriptor) { final String pagePath = pluginDescriptor.getPluginResourcesPath("empty.jsp"); new SimplePageExtension(pagePlaces, PlaceId.ALL_PAGES_FOOTER, "webPagesUsageStatisticsProvider", pagePath) { { register(); } @Override public void fillModel(@NotNull final Map model, @NotNull final HttpServletRequest request) { super.fillModel(model, request); if (isGet(request)) { processGetRequest(request); } } }; } private void readWebPagePatterns(@NotNull final String configFilePath) { for (final File jarFile : myPluginDescriptor.getPluginJars()) { ZipFile zip = null; try { zip = new ZipFile(jarFile); final ZipEntry entry = zip.getEntry(configFilePath); if (entry == null) continue; final BufferedReader reader = new BufferedReader(new InputStreamReader(zip.getInputStream(entry))); try { String line; while ((line = reader.readLine()) != null) { try { myPathPatterns.add(Pattern.compile(line)); } catch (final PatternSyntaxException e) { LOG.info("Invalid web page path pattern: " + line, e); } } break; } finally { reader.close(); } } catch (final IOException e) { LOG.info(e.getLocalizedMessage(), e); } finally { try { if (zip != null) { zip.close(); } } catch (final IOException e) { LOG.info(e.getLocalizedMessage(), e); } } } } }