package org.jenkinsci.plugins.p4.workspace;

import hudson.Extension;
import hudson.model.AutoCompletionCandidates;
import hudson.util.FormValidation;

import java.util.List;
import java.util.logging.Logger;

import org.jenkinsci.plugins.p4.client.ConnectionFactory;
import org.kohsuke.stapler.DataBoundConstructor;
import org.kohsuke.stapler.QueryParameter;

import com.perforce.p4java.client.IClient;
import com.perforce.p4java.client.IClientSummary;
import com.perforce.p4java.impl.mapbased.client.Client;
import com.perforce.p4java.option.server.GetClientsOptions;
import com.perforce.p4java.option.server.SwitchClientViewOptions;
import com.perforce.p4java.server.IOptionsServer;

public class TemplateWorkspaceImpl extends Workspace {

	private final String templateName;
	private final String format;

	private static Logger logger = Logger.getLogger(TemplateWorkspaceImpl.class
			.getName());

	public String getTemplateName() {
		return templateName;
	}

	public String getFormat() {
		return format;
	}

	@Override
	public String getName() {
		return format;
	}

	@Override
	public WorkspaceType getType() {
		return WorkspaceType.TEMPLATED;
	}

	@DataBoundConstructor
	public TemplateWorkspaceImpl(String charset, boolean pinHost,
			String templateName, String format) {
		super(charset, pinHost);
		this.templateName = templateName;
		this.format = format;
	}

	@Override
	public IClient setClient(IOptionsServer connection, String user)
			throws Exception {
		// Check template exists or exit early
		String template = getTemplateName();
		IClient itemplate = connection.getClient(template);
		if (itemplate == null) {
			return null;
		}

		// expands Workspace name if formatters are used.
		String clientName = getFullName();

		IClient iclient = connection.getClient(clientName);
		if (iclient == null) {
			logger.info("P4: Creating template client: " + clientName);
			Client implClient = new Client(connection);
			implClient.setName(clientName);
			connection.createClient(implClient);
			iclient = connection.getClient(clientName);
		}
		// Set owner (not set during create)
		iclient.setOwnerName(user);

		// Root required to switch view; must reload values in iclient.
		iclient.setRoot(getRootPath());
		iclient.update();

		// Use template with client
		SwitchClientViewOptions opts = new SwitchClientViewOptions();
		opts.setForce(true);
		connection.switchClientView(template, clientName, opts);
		iclient = connection.getClient(clientName);
		return iclient;
	}

	@Extension
	public static final class DescriptorImpl extends WorkspaceDescriptor {

		public static final String defaultFormat = "jenkins-${NODE_NAME}-${JOB_NAME}";

		@Override
		public String getDisplayName() {
			return "Template (view generated for each node)";
		}

		/**
		 * Provides auto-completion for workspace names. Stapler finds this
		 * method via the naming convention.
		 * 
		 * @param value
		 *            The text that the user entered.
		 */
		public AutoCompletionCandidates doAutoCompleteTemplateName(
				@QueryParameter String value) {

			AutoCompletionCandidates c = new AutoCompletionCandidates();
			try {
				IOptionsServer iserver = ConnectionFactory.getConnection();
				if (iserver != null && value.length() > 0) {
					List<IClientSummary> list;
					GetClientsOptions opts = new GetClientsOptions();
					opts.setMaxResults(10);
					opts.setNameFilter(value + "*");
					list = iserver.getClients(opts);
					for (IClientSummary l : list) {
						c.add(l.getName());
					}
				}
			} catch (Exception e) {
			}

			return c;
		}

		public FormValidation doCheckTemplateName(@QueryParameter String value) {
			return checkClientName(value);
		}

		public FormValidation doCheckFormat(@QueryParameter final String value) {
			if (value == null || value.isEmpty())
				return FormValidation
						.error("Workspace Name format is mandatory.");

			if (value.contains("${") && value.contains("}")) {
				return FormValidation.ok();
			}
			return FormValidation.error("Workspace Name format error.");
		}
	}
}

@@ -2120,24 +2120,120 @@
 ame(user);%0A%0A
+%09%09// set line endings explicitly (JENKINS-28760)%0A%09%09iclient.setLineEnd(itemplate.getLineEnd());%0A%0A
 %09%09// Root re

Fix JENKINS-28760: Set line endings explicitly for template workspaces