/*
* -----------------------------------------------------------------------
* File: $HeadURL: http://keith-laptop/svn/krs/LanguageTest/trunk/org.thanlwinsoft.languagetest/src/org/thanlwinsoft/languagetest/eclipse/workspace/WorkspaceLanguageManager.java $
* Revision $LastChangedRevision: 1388 $
* Last Modified: $LastChangedDate: 2009-01-31 19:32:00 +0700 (Sat, 31 Jan 2009) $
* Last Change by: $LastChangedBy: keith $
* -----------------------------------------------------------------------
* Copyright (C) 2007 Keith Stribley <devel@thanlwinsoft.org>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library 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 GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
* MA 02110-1301 USA
* -----------------------------------------------------------------------
*/
package org.thanlwinsoft.languagetest.eclipse.workspace;
import java.io.IOException;
import java.io.InputStream;
import java.math.BigDecimal;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Vector;
import org.apache.xmlbeans.XmlException;
import org.apache.xmlbeans.XmlOptions;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IWorkspace;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.swt.graphics.Font;
import org.eclipse.swt.graphics.FontData;
import org.thanlwinsoft.languagetest.MessageUtil;
import org.thanlwinsoft.languagetest.eclipse.LanguageTestPlugin;
import org.thanlwinsoft.languagetest.eclipse.natures.LanguageUserNature;
import org.thanlwinsoft.languagetest.language.test.UniversalLanguage;
import org.thanlwinsoft.schemas.languagetest.module.ConfigType;
import org.thanlwinsoft.schemas.languagetest.module.DescType;
import org.thanlwinsoft.schemas.languagetest.module.LangType;
import org.thanlwinsoft.schemas.languagetest.module.LangTypeType;
import org.thanlwinsoft.schemas.languagetest.module.LanguageModuleDocument;
import org.thanlwinsoft.schemas.languagetest.module.LanguageModuleType;
/** The WorkspaceLanguageManager stores the languages associated with a project.
* Usually one project is used for one Foreign language being learnt. However,
* there may be several different scripts used for the same language. The
* languages for a project are stored in a hidden file in the root of the
* project.
* @author keith
*
*/
public class WorkspaceLanguageManager
{
private IProject userProject = null;
private LangType [] userLanguages = null;
public final static String LANG_FILE = ".languages.xml";
public final static String WORKSPACE_LANG_ID = "WSLANGID";
private static WorkspaceLanguageManager instance = null;
protected WorkspaceLanguageManager()
{
}
protected static WorkspaceLanguageManager get()
{
if (instance == null)
instance = new WorkspaceLanguageManager();
return instance;
}
public static void addLanguage(IProject project, LangTypeType.Enum type,
UniversalLanguage ul, FontData fontData, IProgressMonitor monitor)
{
LangType lang = LangType.Factory.newInstance();
lang.setLang(ul.getCode());
lang.setFont(fontData.getName());
BigDecimal fontSize = BigDecimal.valueOf(fontData.getHeight());
lang.setFontSize(fontSize);
lang.setType(type);
DescType desc = lang.addNewDesc();
desc.setLang("en");
desc.setStringValue(ul.getDescription());
get().setLanguage(project, lang, monitor);
}
public static void addLanguage(IProject project, LangTypeType.Enum type,
UniversalLanguage ul, Font font, IProgressMonitor monitor)
{
FontData fontData = font.getFontData()[0];
addLanguage(project, type, ul, fontData, monitor);
}
public static void addLanguage(IProject project, LangType lang, IProgressMonitor monitor)
{
get().setLanguage(project, lang, monitor);
}
public static synchronized void removeLanguage(IProject project, LangType lang, IProgressMonitor monitor)
{
LanguageModuleDocument doc = get().getProjectLang(project);
LanguageModuleType module = doc.getLanguageModule();
for (int j = 0; j < module.sizeOfLangArray(); j++)
{
LangType trialLang = module.getLangArray(j);
if (trialLang.getLang().equals(lang.getLang()))
{
module.removeLang(j);
get().saveLang(project, doc, monitor);
return;
}
}
}
protected synchronized void setLanguage(IProject project, LangType lang, IProgressMonitor monitor)
{
LanguageModuleDocument doc = getProjectLang(project);
LanguageModuleType module = doc.getLanguageModule();
for (int j = 0; j < module.sizeOfLangArray(); j++)
{
LangType trialLang = module.getLangArray(j);
if (trialLang.getLang().equals(lang.getLang()))
{
trialLang.setFont(lang.getFont());
trialLang.setFontSize(lang.getFontSize());
// is it wise to allow type changes?
trialLang.setType(lang.getType());
// copy accross description array
if (lang.sizeOfDescArray() > 0)
{
for (int k = 0; k < lang.sizeOfDescArray(); k++)
{
trialLang.addNewDesc();
trialLang.setDescArray(k, lang.getDescArray(k));
}
}
saveLang(project, doc, monitor);
return;
}
}
// there is no entry for this language, so we need t create one
int i = module.sizeOfLangArray();
// insert native before the foreign languages
if (lang.getType().equals(LangTypeType.NATIVE))
{
for (i = 0; i < module.sizeOfLangArray() &&
module.getLangArray(i).getType().equals(LangTypeType.NATIVE);
i++) {}
}
module.insertNewLang(i);
module.setLangArray(i, lang);
saveLang(project, doc, monitor);
}
protected synchronized void saveLang(IProject project, LanguageModuleDocument doc,
IProgressMonitor monitor)
{
try
{
IFile langFile = project.getFile(LANG_FILE);
XmlOptions options = new XmlOptions();
options.setCharacterEncoding("UTF-8");
options.setSavePrettyPrint();
if (langFile.exists() == false)
langFile.create(doc.newInputStream(options), 0, monitor);
else
langFile.setContents(doc.newInputStream(options),
0, monitor);
langFile.refreshLocal(0, monitor);
}
catch (CoreException e)
{
LanguageTestPlugin.log(IStatus.WARNING,
MessageUtil.getString("FileNotFound", LANG_FILE),e);
}
}
public IProject getProject(UniversalLanguage ul)
{
IWorkspace workspace = ResourcesPlugin.getWorkspace();
UniversalLanguage ulNoScript =
new UniversalLanguage(ul.getLanguageCode(), ul.getCountryCode(),
ul.getVariant(), "", "");
IProject project = workspace.getRoot().getProject(ulNoScript.getCode());
return project;
}
public static IProject getUserProject()
{
if (get().userProject == null)
{
findUserProjects();
}
return get().userProject;
}
public static LangType [] findUserLanguages()
{
synchronized (get())
{
if (getUserProject() != null)
get().userLanguages = findLanguages(getUserProject());
}
return get().userLanguages;
}
public static LangType [] findUserLanguages(LangTypeType.Enum type)
{
LangType [] langs = findUserLanguages();
Vector<LangType> langSet = new Vector<LangType>();
for(LangType l : langs)
{
if (l.getType().equals(type))
langSet.add((LangType)l.copy());
}
return langSet.toArray(new LangType[langSet.size()]);
}
/**
* Find the active languages of a given type for a project.
* User langauges are appended to the project list.
* @param project
* @param langType
* @return mapping of language codes to UniversalLanguage objects
*/
public static HashMap<String, LangType> findActiveLanguages(IProject project, LangTypeType.Enum langType)
{
HashMap<String, LangType> langs = new HashMap<String, LangType>();
LangType [] userLangs = findUserLanguages();
if (userLangs != null)
{
for (int i = 0; i < userLangs.length; i++)
{
if (langType == null || langType.equals(userLangs[i].getType()))
{
langs.put(userLangs[i].getLang(), userLangs[i]);
}
}
}
LangType [] projectLangs = findLanguages(project);
for (int j = 0; j < projectLangs.length; j++)
{
if (langType == null || langType.equals(projectLangs[j].getType()))
{
if (langs.containsKey(projectLangs[j].getLang()) == false)
langs.put(projectLangs[j].getLang(), projectLangs[j]);
}
}
return langs;
}
public static IProject [] findUserProjects()
{
int openCount = 0;
HashSet<IProject> userProjects = new HashSet<IProject>();
IWorkspace workspace = ResourcesPlugin.getWorkspace();
IProject [] projects = workspace.getRoot().getProjects();
for (int i = 0; i < projects.length; i++)
{
try
{
if (projects[i].isOpen() && projects[i].hasNature(LanguageUserNature.ID))
{
userProjects.add(projects[i]);
if (projects[i].isOpen())
{
openCount++;
synchronized (get())
{
get().userProject = projects[i];
}
}
}
}
catch (CoreException e)
{
e.printStackTrace();
}
}
return (userProjects.toArray(new IProject[userProjects.size()]));
}
static public ConfigType getProjectLangConfig(IProject project)
{
LanguageModuleDocument doc = get().getProjectLang(project);
if (doc == null) return null;
ConfigType config = null;
if (!doc.getLanguageModule().isSetConfig())
{
config = doc.getLanguageModule().addNewConfig();
}
else
{
config = doc.getLanguageModule().getConfig();
}
return config;
}
protected LanguageModuleDocument getProjectLang(IProject project)
{
if (project == null) return null;
IFile langFile = project.getFile(LANG_FILE);
synchronized(get())
{
try
{
if (langFile.isAccessible())
{
InputStream is = langFile.getContents();
XmlOptions options = new XmlOptions();
options.setCharacterEncoding("UTF-8");
options.setLoadUseDefaultResolver();
options.setDocumentType(LanguageModuleDocument.type);
LanguageModuleDocument langDoc =
LanguageModuleDocument.Factory.parse(is);
if (langDoc.getLanguageModule() == null)
langDoc.addNewLanguageModule();
return langDoc;
}
}
catch (CoreException e)
{
LanguageTestPlugin.log(IStatus.WARNING,
MessageUtil.getString("FileNotFound", LANG_FILE),e);
}
catch (XmlException e)
{
LanguageTestPlugin.log(IStatus.WARNING,
MessageUtil.getString("TestModuleReadErrorMsg",
LANG_FILE), e);
}
catch (IOException e)
{
LanguageTestPlugin.log(IStatus.WARNING,
MessageUtil.getString("TestModuleReadErrorMsg",
LANG_FILE), e);
}
}
LanguageModuleDocument doc =
LanguageModuleDocument.Factory.newInstance();
doc.addNewLanguageModule();
doc.getLanguageModule().setCreationTime(new Date().getTime());
doc.getLanguageModule().setId("WORKSPACE_LANG_ID");
return doc;
}
public static LangType [] findLanguages(IProject project)
{
//IWorkspace workspace = ResourcesPlugin.getWorkspace();
LanguageModuleDocument doc = get().getProjectLang(project);
if (doc == null)
{
return new LangType[0];
}
else
{
return get().getProjectLang(project).getLanguageModule().getLangArray();
}
}
}