// Copyright (c) 2003-2005 by Leif Frenzel - see http://leiffrenzel.de
package net.sf.eclipsefp.haskell.ui.wizards;
import java.io.InputStream;
import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import net.sf.eclipsefp.haskell.buildwrapper.BuildWrapperPlugin;
import net.sf.eclipsefp.haskell.core.cabalmodel.CabalSyntax;
import net.sf.eclipsefp.haskell.core.cabalmodel.PackageDescription;
import net.sf.eclipsefp.haskell.core.cabalmodel.PackageDescriptionLoader;
import net.sf.eclipsefp.haskell.core.cabalmodel.PackageDescriptionStanza;
import net.sf.eclipsefp.haskell.core.cabalmodel.RealValuePosition;
import net.sf.eclipsefp.haskell.core.code.ModuleCreationInfo;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.runtime.Assert;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.jface.operation.IRunnableWithProgress;
import org.eclipse.jface.text.IDocument;
import org.eclipse.ui.editors.text.TextFileDocumentProvider;
import org.eclipse.ui.texteditor.IDocumentProvider;
/** <p>the operation that creates a new file from a template.</p>
*
* @author Leif Frenzel
* @author Alejandro Serrano
*/
public class TemplateFileCreationOperation implements IRunnableWithProgress {
private final InputStream stream;
private final String fileExtension;
private final ModuleCreationInfo info;
// the file that is finally generated in this operation
private IFile generatedFile;
public TemplateFileCreationOperation( final ModuleCreationInfo info, final InputStream stream, final String fileExtension ) {
this.info = info;
this.stream = stream;
this.fileExtension = fileExtension;
}
IFile getGeneratedFile() {
return generatedFile;
}
public void setGeneratedFile( final IFile generatedFile ) {
this.generatedFile = generatedFile;
}
public ModuleCreationInfo getInfo() {
return info;
}
// interface methods of IRunnableWithProgress
/////////////////////////////////////////////
@Override
public void run( final IProgressMonitor monitor ) throws InvocationTargetException {
Assert.isNotNull( info );
try {
boolean onlyAdd=false;
if (generatedFile==null){
generatedFile = new TemplateFileGenerator( stream, fileExtension ).createFile( monitor, info );
onlyAdd=true;
}
IProject p=generatedFile.getProject();
IFile f=BuildWrapperPlugin.getCabalFile( p );
IDocumentProvider prov=new TextFileDocumentProvider();
prov.connect( f );
try {
IDocument doc=prov.getDocument( f );
PackageDescription pd=PackageDescriptionLoader.load( doc.get() );
String moduleName=info.getQualifiedModuleName();
if (onlyAdd){
for (PackageDescriptionStanza pds:info.getIncluded()){
RealValuePosition vp=pd.getSameStanza(pds).addToPropertyList( CabalSyntax.FIELD_OTHER_MODULES, moduleName );
if (vp!=null){
vp.updateDocument( doc );
pd=PackageDescriptionLoader.load( doc.get() );
}
}
for (PackageDescriptionStanza pds:info.getExposed()){
RealValuePosition vp=pd.getSameStanza(pds).addToPropertyList( CabalSyntax.FIELD_EXPOSED_MODULES, moduleName );
if (vp!=null){
vp.updateDocument( doc );
pd=PackageDescriptionLoader.load( doc.get() );
}
}
} else {
Set<String> sIncluded=new HashSet<>();
for (PackageDescriptionStanza pds:info.getIncluded()){
sIncluded.add( pds.toTypeName() );
}
Set<String> sExposed=new HashSet<>();
for (PackageDescriptionStanza pds:info.getExposed()){
sExposed.add( pds.toTypeName() );
}
List<PackageDescriptionStanza> pdss=new ArrayList<>( pd.getStanzas() );
for (PackageDescriptionStanza pds:pdss){
if (pds.getType()!=null && pds.isSourceStanza()){
pds=pd.getSameStanza( pds );
RealValuePosition vp=null;
if(sIncluded.contains( pds.toTypeName() )){
vp=pds.addToPropertyList( CabalSyntax.FIELD_OTHER_MODULES, moduleName );
} else {
vp=pds.removeFromPropertyList( CabalSyntax.FIELD_OTHER_MODULES, moduleName );
}
if (vp!=null){
vp.updateDocument( doc );
pd=PackageDescriptionLoader.load( doc.get() );
pds=pd.getSameStanza( pds );
}
if (sExposed.contains( pds.toTypeName() )){
vp=pds.addToPropertyList( CabalSyntax.FIELD_EXPOSED_MODULES, moduleName );
} else {
vp=pds.removeFromPropertyList( CabalSyntax.FIELD_EXPOSED_MODULES, moduleName );
}
if (vp!=null){
vp.updateDocument( doc );
pd=PackageDescriptionLoader.load( doc.get() );
}
}
}
}
prov.saveDocument( monitor, f, doc, true );
} finally {
prov.disconnect( f );
}
// let the listener do its work
// ScionPlugin.getScionInstance( generatedFile ).buildProjectForWorkspace( monitor, false , false);
} catch( CoreException ex ) {
throw new InvocationTargetException( ex );
}
}
}