001: /*
002: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
003: *
004: * Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved.
005: *
006: * The contents of this file are subject to the terms of either the GNU
007: * General Public License Version 2 only ("GPL") or the Common
008: * Development and Distribution License("CDDL") (collectively, the
009: * "License"). You may not use this file except in compliance with the
010: * License. You can obtain a copy of the License at
011: * http://www.netbeans.org/cddl-gplv2.html
012: * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
013: * specific language governing permissions and limitations under the
014: * License. When distributing the software, include this License Header
015: * Notice in each file and include the License file at
016: * nbbuild/licenses/CDDL-GPL-2-CP. Sun designates this
017: * particular file as subject to the "Classpath" exception as provided
018: * by Sun in the GPL Version 2 section of the License file that
019: * accompanied this code. If applicable, add the following below the
020: * License Header, with the fields enclosed by brackets [] replaced by
021: * your own identifying information:
022: * "Portions Copyrighted [year] [name of copyright owner]"
023: *
024: * Contributor(s):
025: *
026: * The Original Software is NetBeans. The Initial Developer of the Original
027: * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
028: * Microsystems, Inc. All Rights Reserved.
029: *
030: * If you wish your version of this file to be governed by only the CDDL
031: * or only the GPL Version 2, indicate your decision by adding
032: * "[Contributor] elects to include this software in this distribution
033: * under the [CDDL or GPL Version 2] license." If you do not indicate a
034: * single choice of license, a recipient has the option to distribute
035: * your version of this file under either the CDDL, the GPL Version 2 or
036: * to extend the choice of license to its licensees as provided above.
037: * However, if you add GPL Version 2 code and therefore, elected the GPL
038: * Version 2 license, then the option applies only if the new code is
039: * made subject to such option by the copyright holder.
040: */
041:
042: package org.netbeans.modules.subversion.ui.copy;
043:
044: import java.io.File;
045: import org.netbeans.modules.subversion.FileInformation;
046: import org.netbeans.modules.subversion.RepositoryFile;
047: import org.netbeans.modules.subversion.Subversion;
048: import org.netbeans.modules.subversion.client.SvnClient;
049: import org.netbeans.modules.subversion.client.SvnClientExceptionHandler;
050: import org.netbeans.modules.subversion.client.SvnProgressSupport;
051: import org.netbeans.modules.subversion.ui.actions.ContextAction;
052: import org.netbeans.modules.subversion.util.Context;
053: import org.netbeans.modules.subversion.util.SvnUtils;
054: import org.openide.nodes.Node;
055: import org.tigris.subversion.svnclientadapter.ISVNInfo;
056: import org.tigris.subversion.svnclientadapter.SVNClientException;
057: import org.tigris.subversion.svnclientadapter.SVNRevision;
058: import org.tigris.subversion.svnclientadapter.SVNUrl;
059:
060: /**
061: *
062: * @author Tomas Stupka
063: */
064: public class CreateCopyAction extends ContextAction {
065:
066: /** Creates a new instance of CreateCopyAction */
067: public CreateCopyAction() {
068:
069: }
070:
071: protected String getBaseName(Node[] activatedNodes) {
072: return "CTL_MenuItem_Copy"; // NOI18N
073: }
074:
075: protected int getFileEnabledStatus() {
076: return FileInformation.STATUS_MANAGED
077: & ~FileInformation.STATUS_NOTVERSIONED_EXCLUDED;
078: }
079:
080: protected int getDirectoryEnabledStatus() {
081: return FileInformation.STATUS_MANAGED
082: & ~FileInformation.STATUS_NOTVERSIONED_EXCLUDED
083: & ~FileInformation.STATUS_NOTVERSIONED_NEWLOCALLY;
084: }
085:
086: protected boolean enable(Node[] nodes) {
087: return nodes != null && nodes.length == 1
088: && getContext(nodes).getRoots().size() > 0;
089: }
090:
091: protected void performContextAction(final Node[] nodes) {
092:
093: if (!Subversion.getInstance().checkClientAvailable()) {
094: return;
095: }
096:
097: Context ctx = getContext(nodes);
098:
099: final File root = ctx.getRootFiles()[0];
100: File[] files = Subversion.getInstance().getStatusCache()
101: .listFiles(ctx, FileInformation.STATUS_LOCAL_CHANGE);
102:
103: final boolean hasChanges = files.length > 0;
104: final SVNUrl repositoryUrl;
105: final SVNUrl fileUrl;
106: try {
107: repositoryUrl = SvnUtils.getRepositoryRootUrl(root);
108: fileUrl = SvnUtils.getRepositoryUrl(root);
109: } catch (SVNClientException ex) {
110: SvnClientExceptionHandler.notifyException(ex, true, true);
111: return;
112: }
113: final RepositoryFile repositoryFile = new RepositoryFile(
114: repositoryUrl, fileUrl, SVNRevision.HEAD);
115:
116: final CreateCopy createCopy = new CreateCopy(repositoryFile,
117: root, hasChanges);
118:
119: if (createCopy.showDialog()) {
120: // XXX don't close dialog if error occures!
121: ContextAction.ProgressSupport support = new ContextAction.ProgressSupport(
122: this , nodes) {
123: public void perform() {
124: performCopy(createCopy, this );
125: }
126: };
127: support.start(createRequestProcessor(nodes));
128: }
129: }
130:
131: private void performCopy(CreateCopy createCopy,
132: SvnProgressSupport support) {
133: RepositoryFile toRepositoryFile = createCopy
134: .getToRepositoryFile();
135:
136: try {
137: SvnClient client;
138: try {
139: client = Subversion.getInstance().getClient(
140: toRepositoryFile.getRepositoryUrl());
141: } catch (SVNClientException ex) {
142: SvnClientExceptionHandler.notifyException(ex, true,
143: true);
144: return;
145: }
146:
147: if (!toRepositoryFile.isRepositoryRoot()) {
148: SVNUrl folderToCreate = toRepositoryFile
149: .removeLastSegment().getFileUrl();
150: ISVNInfo info = null;
151: try {
152: info = client.getInfo(folderToCreate);
153: } catch (SVNClientException ex) {
154: if (!SvnClientExceptionHandler.isWrongUrl(ex
155: .getMessage())) {
156: throw ex;
157: }
158: }
159:
160: if (support.isCanceled()) {
161: return;
162: }
163:
164: if (info == null) {
165: client
166: .mkdir(
167: folderToCreate,
168: true,
169: "[Netbeans SVN client generated message: create a new folder for the copy]: '\n"
170: + createCopy.getMessage()
171: + "\n'"); // NOI18N
172: } else {
173: if (createCopy.getLocalFile().isFile()) {
174: // we are copying a file to a destination which already exists. Even if it's a folder - we don't use the exactly same
175: // as the commandline svn client:
176: // - the remote file specified in the GUI has to be exactly the file which has to be created at the repository.
177: // - if the destination is an existent folder the file won't be copied into it, as the svn client would do.
178: throw new SVNClientException(
179: "File allready exists");
180: } else {
181: // XXX warnig: do you realy want to? could be already a project folder!
182: }
183: }
184: }
185:
186: if (support.isCanceled()) {
187: return;
188: }
189:
190: if (createCopy.isLocal()) {
191: client.copy(createCopy.getLocalFile(), toRepositoryFile
192: .getFileUrl(), createCopy.getMessage());
193: } else {
194: RepositoryFile fromRepositoryFile = createCopy
195: .getFromRepositoryFile();
196: client.copy(fromRepositoryFile.getFileUrl(),
197: toRepositoryFile.getFileUrl(), createCopy
198: .getMessage(), fromRepositoryFile
199: .getRevision());
200: }
201:
202: if (support.isCanceled()) {
203: return;
204: }
205:
206: if (createCopy.switchTo()) {
207: SwitchToAction.performSwitch(toRepositoryFile,
208: createCopy.getLocalFile(), support);
209: }
210:
211: } catch (SVNClientException ex) {
212: support.annotate(ex);
213: }
214: }
215: }
|