Exemple #1
0
void ExtensionsWizard::OnWizardFinished(wxWizardEvent &e)
{
	String extensionName = conversions::to_utf16(m_pageGeneral->getExtensionName());
	String extensionDescription = conversions::to_utf16(m_pageGeneral->getExtensionDescription());
	String extensionAuthor = conversions::to_utf16(m_pageGeneral->getExtensionAuthor());
	shared_ptr<ExtensionsWizardPageTemplate::TemplateDetails> extensionTemplate = m_pageTemplate->getTemplate();
	const ExtensionsWizardPageTemplate::TemplateDetails::Files &extensionFiles = extensionTemplate->getFiles();

	ExtensionID extensionID = ExtensionID::generate();

	String rootPath = ExtensionsSystem::instance()->getDataPath();
	String extensionPath = utils::makeFolderPath(rootPath, extensionID.toUTF16());

	shared_ptr<XMLDocument> document(OS_NEW XMLDocument());
	shared_ptr<XMLNode> nodeRoot = document->create(OS_EXTENSION_XML_NODE_ROOT);
	nodeRoot->setAttributeString(OS_EXTENSION_XML_NODE_ROOT_ID, extensionID.getString());
	nodeRoot->setAttributeString(OS_EXTENSION_XML_NODE_ROOT_NAME, extensionName);
	nodeRoot->setAttributeString(OS_EXTENSION_XML_NODE_ROOT_DESCRIPTION, extensionDescription);
	nodeRoot->setAttributeString(OS_EXTENSION_XML_NODE_ROOT_AUTHOR, extensionAuthor);
	nodeRoot->setAttributeString(OS_EXTENSION_XML_NODE_ROOT_VERSION_CODE, _S("1"));
	nodeRoot->setAttributeString(OS_EXTENSION_XML_NODE_ROOT_VERSION_NAME, _S("0.1"));
	nodeRoot->setAttributeString(OS_EXTENSION_XML_NODE_ROOT_ICON, _S("icon.png"));
	nodeRoot->setAttributeString(OS_EXTENSION_XML_NODE_ROOT_LOGO, _S("logo.png"));

	shared_ptr<XMLNode> nodeScripts;
	ExtensionsWizardPageTemplate::TemplateDetails::Files::const_iterator i;
	for(i = extensionFiles.begin(); i != extensionFiles.end(); ++i)
	{
		if((*i).script)
		{
			if(nodeScripts == nullptr)
				nodeScripts = nodeRoot->addChild(OS_EXTENSION_XML_NODE_SCRIPTS);

			shared_ptr<XMLNode> nodeScript = nodeScripts->addChild(OS_EXTENSION_XML_NODE_SCRIPT);
			nodeScript->setAttributeString(OS_EXTENSION_XML_NODE_SCRIPT_PATH, (*i).target);
			// TODO: temp
			nodeScript->setAttributeString(OS_EXTENSION_XML_NODE_SCRIPT_LANGUAGE, "python");
		}
	}

	String documentString;
	if(document->writeString(documentString) == false)
	{
		OS_ASSERTFALSE();
		Application::instance()->reportError("Internal error generating extension's xml, please report it", true);
		return;
	}

	if(XMLManager::instance()->validateString(documentString, XMLSchema::fromFile(utils::makeFilePath(utils::makeFolderPath(Options::instance()->getSharePath(), OS_SCHEMAS_PATH), OS_EXTENSIONS_EXTENSION_SCHEMA))) == false)
	{
		OS_ASSERTFALSE();
		Application::instance()->reportError("Internal error validating extension's xml, please report it", true);
		return;
	}

	if(FileSystem::instance()->ensureDirectory(extensionPath) == false)
	{
		Application::instance()->reportError("Cannot create directory '" + extensionPath + "'", true);
		return;
	}

	for(i = extensionFiles.begin(); i != extensionFiles.end(); ++i)
	{
		String targetFile = utils::makeFilePath(extensionPath, (*i).target);
		String sourceFile = utils::makeFilePath(extensionTemplate->getFolder(), (*i).source);

		String targetPath = FileSystem::instance()->getFilePath(targetFile);
		if(FileSystem::instance()->ensureDirectory(targetPath) == false)
		{
			Application::instance()->reportError("Cannot create directory '" + targetPath + "'", true);
			return;
		}

		if(FileSystem::instance()->copyFile(sourceFile, targetFile) == false)
		{
			Application::instance()->reportError("Cannot copy file '" + sourceFile + "' to '" + targetFile + "'", true);
			return;
		}

		if((*i).macro)
		{
			// Open file, do replaces and save.
			String data;
			TextFile::readFile(targetFile, data);

			data = data.replace_all("{extension_id}", extensionID.getString());
			data = data.replace_all("{extension_name}", extensionName);
			data = data.replace_all("{extension_description}", extensionDescription);
			data = data.replace_all("{extension_author}", extensionAuthor);
			UniqueID uniqueID = UniqueID::generate();
			data = data.replace_all("{unique_id}", uniqueID.getString());

			TextFile file;
			file.open(targetFile, TextFile::ofWrite);
			file.writeLine(data);
			file.close();
		}
	}

	String documentFile = utils::makeFilePath(extensionPath, OS_MANIFESTXML);
	if(document->writeFile(documentFile) == false)
	{
		Application::instance()->reportError("Error writing file '" + documentFile + "'", true);
		return;
	}

	OS_ASSERT(XMLManager::instance()->validateFile(documentFile, XMLSchema::fromFile(utils::makeFilePath(utils::makeFolderPath(Options::instance()->getSharePath(), OS_SCHEMAS_PATH), OS_EXTENSIONS_EXTENSION_SCHEMA))));

	if(m_pageFinish->getOpenFolder())
		Application::instance()->shell(extensionPath);

	Application::instance()->reloadExtensions();
}
Exemple #2
0
bool ExtensionsExtension::init(const ExtensionID &id, const Path &path)
{
	OS_ASSERT(path.empty() == false);
	OS_ASSERT(m_path.empty());

	m_path = path;

	//String filename = utils::makeFilePath(path, id.toUTF16() + ".xml"); // 0.13
	String filename = utils::makeFilePath(path, OS_MANIFESTXML); // 0.14
	if(FileSystem::instance()->fileExists(filename) == false)
		return false;
	
	shared_ptr<XMLDocument> document(OS_NEW XMLDocument(XMLSchema::fromFile(utils::makeFilePath(utils::makeFolderPath(Options::instance()->getSharePath(), OS_SCHEMAS_PATH), OS_EXTENSIONS_EXTENSION_SCHEMA))));
	if(document->parseFile(filename) == false)
		return false;

	String languagesPath = utils::makeFolderPath(path.path(), OS_LANGUAGES_PATH);
	if(FileSystem::instance()->directoryExists(languagesPath))
	{
		m_languageFolder.reset(OS_NEW LanguageFolder());
		m_languageFolder->addPath(languagesPath);
	}

	String htdocsPath = utils::makeFolderPath(path.path(), OS_HTDOCS_PATH);
	if(FileSystem::instance()->directoryExists(htdocsPath))
	{
		// TODO: Qui dovrei fare un'opzione a livello di xml extension, che stabilisce il nome della virtual-directory. Se omesso, è l'ID.
		// Per ora, forzo l'unico caso in cui mi servirebbe.
		String virtualName = id.toUTF16();
		if(id.toUTF16() == OS_EXTENSIONS_CORE)
			virtualName = OS_HTDOCS_PATH;

		m_httpDirectory.reset(OS_NEW HttpPhysicalDirectory(virtualName, htdocsPath));
	}

	// Auto-discovery IdeSkinSimple
	String skinsPath = utils::makeFolderPath(path.path(), "skins");
	{
		if(FileSystem::instance()->directoryExists(skinsPath))
		{
			StringList skins;
			FileSystem::instance()->getFiles(skinsPath, skins, false);
			for(StringList::const_iterator i = skins.begin(); i != skins.end(); ++i)
			{
				String config = "/skins/" + *i;
				String title = FileSystem::instance()->getFileTitle(*i);
				shared_ptr<IdeSkinSimple> skin(OS_NEW IdeSkinSimple());
				if(skin->init(get_this_ptr(), config, title))
					m_skins.push_back(skin);
			}
		}
	}

	shared_ptr<XMLNode> root = document->getRoot();

	if(root->getAttributeString(OS_EXTENSION_XML_NODE_ROOT_ID) != id.getString()) // Ensure that the directory name is equal to ID.
		return false;

	m_id = id;
	m_name = root->getAttributeString(OS_EXTENSION_XML_NODE_ROOT_NAME);	
	m_description = root->getAttributeString(OS_EXTENSION_XML_NODE_ROOT_DESCRIPTION);
	m_content = root->getAttributeString(OS_EXTENSION_XML_NODE_ROOT_CONTENT);
	m_category = root->getAttributeString(OS_EXTENSION_XML_NODE_ROOT_CATEGORY);
	m_tags = root->getAttributeString(OS_EXTENSION_XML_NODE_ROOT_TAGS);
	m_trust = root->getAttributeString(OS_EXTENSION_XML_NODE_ROOT_TRUST);
	m_author = root->getAttributeString(OS_EXTENSION_XML_NODE_ROOT_AUTHOR);
	m_versionCode = root->getAttributeInt32(OS_EXTENSION_XML_NODE_ROOT_VERSION_CODE);
	m_versionName = root->getAttributeString(OS_EXTENSION_XML_NODE_ROOT_VERSION_NAME);
	m_compatibility = root->getAttributeInt32(OS_EXTENSION_XML_NODE_ROOT_COMPATIBILITY);
	/*
	if(m_version.fromString(root->getAttributeString(OS_EXTENSION_XML_NODE_ROOT_VERSION).to_ascii()) == false)
		return false;
	String compatibility = root->getAttributeString(OS_EXTENSION_XML_NODE_ROOT_COMPATIBILITY);
	if( (compatibility.empty() == false) && (m_compatibility.fromString(compatibility.to_ascii()) == false) )
		return false;
	*/
	m_homepage = root->getAttributeString(OS_EXTENSION_XML_NODE_ROOT_HOMEPAGE);
	m_icon = root->getAttributeString(OS_EXTENSION_XML_NODE_ROOT_ICON);
	m_logo = root->getAttributeString(OS_EXTENSION_XML_NODE_ROOT_LOGO);
	
	NotificationsManager::instance()->notify(_S("Loading extension: ") + m_name);
	
	shared_ptr<XMLNode> nodeFiles = document->getRoot()->getNode(OS_EXTENSION_XML_NODE_SCRIPTS);
	if(nodeFiles != nullptr)
	{
		shared_ptr<XMLNodes> files = nodeFiles->getNodes();
		for(XMLNodes::const_iterator i = files->begin(); i != files->end(); ++i)
		{
			String scriptPath = utils::makeFilePath(path, (*i)->getAttributeString(OS_EXTENSION_XML_NODE_SCRIPT_PATH));
			String scriptLanguage = (*i)->getAttributeString(OS_EXTENSION_XML_NODE_SCRIPT_LANGUAGE);

			shared_ptr<IExtensionsCodeProvider> codeProvider = ExtensionsSystem::instance()->getCodeProvider(scriptLanguage);
			if(codeProvider == nullptr)
			{
				OS_LOG_ERROR(_S("Invalid script language '") + scriptLanguage + _S("'"));
				return false;
			}

			shared_ptr<IExtensionsCodeContext> context = codeProvider->createContext();
			if(context == nullptr)
			{
				OS_LOG_ERROR(_S("Cannot create context for script language '") + scriptLanguage + _S("'"));
				return false;
			}

			if(context->parseFile(scriptPath))
				m_contexts.push_back(context);				
			else
				OS_LOG_ERROR(_S("Cannot parse extension file '") + scriptPath + _S("'"));
		}
	}
	
	return true;
}