/* Copyright (c) 2013-2014, Perforce Software, Inc. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 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. 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 PERFORCE SOFTWARE, INC. BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ package com.perforce.polarion.repository.provider; import java.util.ArrayList; import java.util.Date; import java.util.List; import com.perforce.p4java.core.IChangelist; import com.perforce.p4java.core.IChangelistSummary; import com.perforce.p4java.core.file.FileSpecBuilder; import com.perforce.p4java.core.file.IFileSpec; import com.perforce.p4java.option.server.GetChangelistsOptions; import com.perforce.p4java.server.IOptionsServer; import com.polarion.core.util.ObjectUtils; import com.polarion.platform.internal.service.repository.LocationChangeMetaData; import com.polarion.platform.repository.external.IExternalRepositoryProvider; import com.polarion.platform.service.repository.ILocationChangeMetaData; import com.polarion.platform.service.repository.IRevisionMetaData; import com.polarion.platform.service.repository.RepositoryException; import com.polarion.subterra.base.data.identification.IContextId; import com.polarion.subterra.base.location.ILocation; import com.polarion.subterra.base.location.Location; /** * @author <a href="mailto:pallen@perforce.com">Paul Allen</a>, Perforce * Software */ public class P4ExternalRepositoryProvider implements IExternalRepositoryProvider { protected static final String ID = "p4"; /** * @return unique id of this provider */ @Override public String getProviderId() { return ID; } /** * @return new empty configuration */ @Override public IExternalRepositoryConfiguration createEmptyConfiguration() { return new P4RepositoryConfiguration(); } /** * Creates a repository for the configuration. * * @contextId * @configuration - filled configuration * @callback * @return OFconfigured repository */ @Override public IExternalRepository getRepository(IContextId contextId, IExternalRepositoryConfiguration configuration, IExternalRepositoryCallback callback) { return new P4Repository(contextId, (P4RepositoryConfiguration) configuration, callback); } private static class P4Repository implements IExternalRepository { private final IContextId contextId; private P4RepositoryConfiguration config; private final IExternalRepositoryCallback callback; /** * @param contextId * @param configuration * @param callback */ public P4Repository(IContextId contextId, P4RepositoryConfiguration configuration, IExternalRepositoryCallback callback) { this.contextId = contextId; config = configuration; this.callback = callback; } /* * (non-Javadoc) * * @see * com.polarion.platform.repository.external.IExternalRepositoryProvider * .IExternalRepository#getContextId() */ @Override public IContextId getContextId() { return contextId; } /* * (non-Javadoc) * * @see * com.polarion.platform.repository.external.IExternalRepositoryProvider * .IExternalRepository#getRevisionViewURL(java.lang.String) */ @Override public String getRevisionViewURL(String revision) { String base = config.getBrowserBaseURL(); if (base != null) { base = cleanURL(base); String url = base + "/changes/" + revision; return url; } return null; } @Override public String getViewLocationDiffURL( ILocationChangeMetaData locationChangeMetaData) { String base = config.getBrowserBaseURL(); if (base != null) { base = cleanURL(base); ILocation toRev = locationChangeMetaData.getChangeLocationTo(); String path = toRev.getLocationPath(); String change = toRev.getRevision(); String hex = Integer.toHexString(path.hashCode()); String url = base + "/changes/" + change + "#" + hex; return url; } return null; } @Override public String getViewLocationURL( ILocationChangeMetaData locationChangeMetaData) { String base = config.getBrowserBaseURL(); if (base != null) { base = cleanURL(base); ILocation toRev = locationChangeMetaData.getChangeLocationTo(); String path = toRev.getLocationPath(); String url = base + "/files/" + path; return url; } return null; } private String cleanURL(String url) { if (url.endsWith("/")) { url = url.substring(0, url.length() - 1); } return url; } /* * (non-Javadoc) * * @see * com.polarion.platform.repository.external.IExternalRepositoryProvider * .IExternalRepository#poll(com.polarion.platform.repository.external. * IExternalRepositoryProvider.IExternalRepository.PollMode) */ @Override public void poll(PollMode mode) { if (mode == null) { throw new IllegalArgumentException("mode is null"); } String lastRevision = callback.getRememberedState(this); int lastChange = 1; try { // build fileSpec in client syntax for query String clientPath = "//" + config.getP4Client() + "/..."; if (lastRevision != null && !mode.equals(PollMode.FROM_FIRST)) { String range = "@" + lastRevision + ",#head"; clientPath += range; lastChange = Integer.parseInt(lastRevision); } List<IFileSpec> fileSpec; fileSpec = FileSpecBuilder.makeFileSpecList(clientPath); // connect to Perforce and fetch change based on revision ID IOptionsServer p4 = ConnectionFactory.getConnection(config); GetChangelistsOptions opts = new GetChangelistsOptions(); List<IChangelistSummary> changes; changes = p4.getChangelists(fileSpec, opts); p4.disconnect(); // push new each change to callback for (IChangelistSummary c : changes) { if (c.getId() > lastChange) { lastChange = c.getId(); } callback.revisionAdded(this, "" + c.getId()); } lastRevision = "" + lastChange; } catch (Exception e) { throw new RepositoryException(e); } finally { callback.setRememberedState(this, lastRevision); } } @Override public boolean allowsAutoPolling() { return false; } @Override public void startAutoPolling() { // empty } @Override public void stopAutoPolling() { // empty } /** * Returns the Perforce Changelist meta-data */ @Override public IRevisionMetaData getRevisionMetaData(String revision) { try { // connect to Perforce and fetch change based on revision ID int changeId = Integer.parseInt(revision); IOptionsServer p4 = ConnectionFactory.getConnection(config); final IChangelist change = p4.getChangelist(changeId); p4.disconnect(); return new IRevisionMetaData() { @Override public String getAuthor() { return change.getUsername(); } @Override public Date getDate() { return change.getDate(); } @Override public String getDescription() { return change.getDescription(); } @Override public String getName() { return change.getClientId(); } }; } catch (Exception e) { throw new RepositoryException(e); } } /** * Returns Perforce configuration */ @Override public IExternalRepositoryConfiguration getConfiguration() { return config; } /** * Reconfigures Perforce configuration */ @Override public void reconfigure( IExternalRepositoryConfiguration newConfiguration) { config = (P4RepositoryConfiguration) newConfiguration; } /** * Builds a list of file revisions in a changelist */ @Override public List<ILocationChangeMetaData> getChangedLocations(String change) { List<ILocationChangeMetaData> list = null; try { // connect to Perforce and fetch change based on revision ID int changeId = Integer.parseInt(change); IOptionsServer p4 = ConnectionFactory.getConnection(config); final IChangelist changelist = p4.getChangelist(changeId); p4.disconnect(); // build list of revisions list = new ArrayList<ILocationChangeMetaData>(); for (IFileSpec r : changelist.getFiles(true)) { LocationChangeMetaData data = new LocationChangeMetaData(); // Set location of revision String toPath = r.getDepotPathString(); ILocation toLocation = getLocation(toPath, change); String fromPath = r.getFromFile(); ILocation fromLocation = getLocation(fromPath, change); // Set action of revision switch (r.getAction()) { case ADD: case IMPORT: data.setCreated(true); data.setToLoc(toLocation); break; case EDIT: data.setModified(true); data.setToLoc(toLocation); break; case DELETE: data.setRemoved(true); data.setToLoc(toLocation); break; case BRANCH: case INTEGRATE: data.setCopied(true); data.setToLoc(toLocation); data.setToLoc(fromLocation); break; case MOVE_ADD: data.setMoved(true); data.setToLoc(toLocation); data.setToLoc(fromLocation); break; case MOVE_DELETE: data.setRemoved(true); data.setToLoc(toLocation); data.setToLoc(fromLocation); break; default: break; } // add to list list.add(data); } } catch (Exception e) { throw new RepositoryException(e); } return list; } private ILocation getLocation(String path, String revision) { if (path != null && !path.startsWith("/")) { path = "/" + path; } if (ObjectUtils.emptyString(revision)) { return Location.getLocationWithRepository(config.getId(), path); } return Location.getLocationWithRepositoryAndRevision( config.getId(), path, revision); } } }
# | Change | User | Description | Committed | |
---|---|---|---|---|---|
#3 | 16756 | Paul Allen | Expose static inner class. | ||
#2 | 16717 | Paul Allen | Clean up code to protect against 'null' from paths for ADD and EDIT cases. | ||
#1 | 15897 | Matt Attaway | Pull changes after the rename in from Paul's dev branch so code will go back smoothly | ||
//guest/paul_allen/dev/p4-polarion/main/src/com/perforce/polarion/repository/provider/P4ExternalRepositoryProvider.java | |||||
#2 | 9759 | Paul Allen |
Code review fixes for: - PollMode - ViewURL - Plugin ID |
||
#1 | 9756 | Paul Allen |
Changed Polarion name space to Perforce: com.perforce.polarion.repository.provider |
||
//guest/paul_allen/dev/p4-polarion/main/src/com/polarion/platform/repository/external/internal/p4/P4ExternalRepositoryProvider.java | |||||
#1 | 9723 | Paul Allen | Initial import of P4 Polarion plugin code |