/* Copyright (C) 2009 Mobile Sorcery AB
This program is free software; you can redistribute it and/or modify it
under the terms of the Eclipse Public License v1.0.
This program is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the Eclipse Public License v1.0 for
more details.
You should have received a copy of the Eclipse Public License v1.0 along
with this program. It is also available at http://www.eclipse.org/legal/epl-v10.html
*/
package com.mobilesorcery.sdk.finalizer.core;
import java.io.IOException;
import java.io.LineNumberReader;
import java.io.Reader;
import java.lang.reflect.InvocationTargetException;
import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.SubProgressMonitor;
import org.eclipse.jface.operation.IRunnableWithProgress;
import com.mobilesorcery.sdk.core.CoreMoSyncPlugin;
import com.mobilesorcery.sdk.core.IBuildConfiguration;
import com.mobilesorcery.sdk.core.IBuildResult;
import com.mobilesorcery.sdk.core.IBuildSession;
import com.mobilesorcery.sdk.core.IBuildVariant;
import com.mobilesorcery.sdk.core.MoSyncBuilder;
import com.mobilesorcery.sdk.core.MoSyncProject;
import com.mobilesorcery.sdk.core.MoSyncTool;
import com.mobilesorcery.sdk.profiles.IProfile;
import com.mobilesorcery.sdk.profiles.IVendor;
public class FinalizerParser {
public static final String FINALIZER_PROPERTY_PREFIX = "finalizer";
public static final String AUTO_CHANGE_CONFIG = FINALIZER_PROPERTY_PREFIX + ":auto.change.config";
public static final String BUILD_CONFIG = FINALIZER_PROPERTY_PREFIX + ":build.config";
public class ParseException extends Exception {
private static final long serialVersionUID = -9055537164752470136L;
public ParseException(String msg, int line) {
super("Line " + line + ": " + msg); //$NON-NLS-1$ //$NON-NLS-2$
}
}
private static final String PATTERN_STR = "begin (.*)/(.*) end"; //$NON-NLS-1$
final static Pattern finalizerPattern = Pattern.compile(PATTERN_STR);
private final IProject project;
private final String cfgId;
/**
* Creates a new parser
* @param project
* @param cfgId <code>null</code> if the project's active
* build configuration should be used
*/
public FinalizerParser(IProject project, String cfgId) {
this.project = project;
this.cfgId = cfgId;
}
public FinalizerParser(IProject project) {
this(project, null);
}
public void execute(Reader script, IProgressMonitor monitor) throws IOException, ParseException, InvocationTargetException,
InterruptedException {
ArrayList<IBuildVariant> variantsToBuild = new ArrayList<IBuildVariant>();
MoSyncProject project = MoSyncProject.create(this.project);
//autoSwitchConfiguration(project);
int lineNo = 1;
LineNumberReader lines = new LineNumberReader(script);
for (String line = lines.readLine(); line != null; line = lines.readLine()) {
IProfile profileToBuild = parse(project, line, lineNo);
if (profileToBuild != null) {
IBuildConfiguration cfg = this.cfgId == null ? project.getActiveBuildConfiguration() : project.getBuildConfiguration(cfgId);
IBuildVariant variant = MoSyncBuilder.getVariant(project, profileToBuild, cfg);
variantsToBuild.add(variant);
}
lineNo++;
}
if (variantsToBuild.isEmpty()) {
throw new ParseException(Messages.FinalizerParser_ParseError_0, 0);
}
IBuildSession buildSession = MoSyncBuilder.createFinalizerBuildSession(variantsToBuild);
IRunnableWithProgress buildJob = MoSyncBuilder.createBuildJob(project.getWrappedProject(), buildSession, variantsToBuild);
buildJob.run(monitor);
}
private IProfile parse(MoSyncProject project, String line, int lineNo) throws ParseException {
if (line.trim().length() == 0 || line.trim().startsWith("#")) { //$NON-NLS-1$
return null;
}
Matcher m = finalizerPattern.matcher(line);
int groups = m.groupCount();
if (m.matches() && groups == 2) {
String vendorName = m.group(1).trim();
String profileName = m.group(2).trim();
IVendor vendor = project.getProfileManager().getVendor(vendorName);
if (vendor == null) {
throw new ParseException(MessageFormat.format(Messages.FinalizerParser_ParseError_UnknownVender, vendorName), lineNo);
}
IProfile profile = vendor.getProfile(profileName);
if (profile == null) {
throw new ParseException(MessageFormat.format(Messages.FinalizerParser_ParseError_UnknownProfile, profileName), lineNo);
}
return profile;
} else {
throw new ParseException(Messages.FinalizerParser_ParseError_3, lineNo);
}
}
public String extractScriptFromProject(MoSyncProject project) {
StringBuffer result = new StringBuffer();
result.append(MessageFormat.format(Messages.FinalizerParser_ScriptBoilerplate, project.getName()));
IProfile[] profiles = project.getFilteredProfiles();
if (profiles.length == 0) {
result.append(Messages.FinalizerParser_ScriptNoProfiles);
}
for (int i = 0; i < profiles.length; i++) {
result.append("begin " + profiles[i].toString() + " end\n"); //$NON-NLS-1$ //$NON-NLS-2$
}
return result.toString();
}
/**
* If applicable, changes the active configuration of the project
* to whatever is set in the project's "Finalizer" properties page.
* @param project
*/
/*public static void autoSwitchConfiguration(MoSyncProject project) {
if (project != null && PropertyUtil.getBoolean(project, AUTO_CHANGE_CONFIG)) {
String buildConfiguration = project.getProperty(BUILD_CONFIG);
if (project.areBuildConfigurationsSupported()) {
project.setActiveBuildConfiguration(buildConfiguration);
}
}
}*/
}