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(); }
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; }