gradle plugin copy without default excludes - gradle-plugin

I want to get some dependency artifact and copy the content into a specific location.
This works well in general, but not for files called e.g. .gitignore.
I found that those are default excludes.
How can i disable those default exclude, by using the Java-Gradle-API in my plugin code?
project.copy( spec -> {
spec.from (project.zipTree(artifact.getFile()));
spec.into( tf.toFile());
//spec.setExcludes(Collections.emptyList()); // does not work
});
Also i tried to the setExcludes in the from/into copyspec.
Frank

I found a solution, but i don't like it, because it modifies the globally visible defaultExcludes:
private static void withoutDefaultExcludes( Runnable r ) {
String[] defaultExcludes = org.apache.tools.ant.DirectoryScanner.getDefaultExcludes();
try {
for( String defaultExclude : defaultExcludes) {
org.apache.tools.ant.DirectoryScanner.removeDefaultExclude(defaultExclude);
}
r.run();
}
finally {
for( String defaultExclude : defaultExcludes) {
org.apache.tools.ant.DirectoryScanner.addDefaultExclude(defaultExclude);
}
}
}
withoutDefaultExcludes( () -> {
project.copy( spec -> {
spec.from (project.zipTree(artifact.getFile()));
spec.into( tf.toFile());
});
});

Related

TornadoFX:proper way to bind model

I was taking a look at this :
tornadofx
and tried to expand on it with database connection and little more options, (not all of them make sense, but its just playing in a sandbox).
Even though table can be directly edited and the data will persist in database, i did try to do edit through text fields too. actual table editing would happen through different view and not table itself, as i said its just example.
Database used is Jetbrains Exposed.
object Categories : IntIdTable() {
val name = varchar("name", 64).uniqueIndex()
val description = varchar("description", 128)
}
class Category(id: EntityID<Int>) : IntEntity(id) {
companion object : IntEntityClass<Category>(Categories)
var name by Categories.name
var description by Categories.description
override fun toString(): String {
return "Category(name=\"$name\", description=\"$description\")"
}
}
now controller looks something like this, functions are just rudimentary and picked as an example.
typealias ModelToDirtyState = Map.Entry<CategoryModel, TableColumnDirtyState<CategoryModel>>
class CategoryModel() : ItemViewModel<Category>() {
val name: SimpleStringProperty = bind(Category::name)
val description: SimpleStringProperty = bind(Category::description)
}
class DBController : Controller() {
val categories: ObservableList<CategoryModel> by lazy {
transaction {
SchemaUtils.create(Categories)
Category.all().map {
CategoryModel().apply {
item = it
}
}.observable()
}
}
init {
Database.connect(
"jdbc:mysql://localhost:3306/test", driver = "com.mysql.cj.jdbc.Driver",
user = "test", password = "test"
)
TransactionManager.manager.defaultIsolationLevel = Connection.TRANSACTION_SERIALIZABLE
}
fun deleteCategory(model: CategoryModel) {
runAsync {
transaction {
model.item.delete()
}
}
categories.remove(model)
}
fun updateCategory(model: CategoryModel) {
transaction {
Categories.update {
model.commit()
}
}
}
fun commitDirty(modelDirtyMappings: Sequence<ModelToDirtyState>) {
transaction {
modelDirtyMappings.filter { it.value.isDirty }.forEach {
it.key.commit()
println(it.key)// commit value to database
it.value.commit() // clear dirty state
}
}
}
Just to quickly comment on controller, delete method works as "intended" however the update one does not, it does not work in sense that after using delete item is remove both from database and tableview(underlying list) itself, and when i do update its not, now i know the reason, i call remove manually on both database and list, now for update perhaps i could do change listener, or maybe tornadofx can do this for me, i just cant set it up to do it. Following code will make things clearer i think.
class CategoryEditor : View("Categories") {
val categoryModel: CategoryModel by inject()
val dbController: DBController by inject()
var categoryTable: TableViewEditModel<CategoryModel> by singleAssign()
var categories: ObservableList<CategoryModel> by singleAssign()
override val root = borderpane {
categories = dbController.categories
center = vbox {
buttonbar {
button("Commit") {
action {
dbController.commitDirty(categoryTable.items.asSequence())
}
}
button("Roll;back") {
action {
categoryTable.rollback()
}
}
// This model only works when i use categorytable.tableview.selected item, if i use categoryModel, list gets updated but not the view itself
// Question #1 how to use just categoryModel variable without need to use categorytable.tableview.selecteditem
button("Delete ") {
action {
val model = categoryTable.tableView.selectedItem
when (model) {
null -> return#action
else -> dbController.deleteCategory(model)
}
}
}
//And here no matter what i did i could not make the view update
button("Update") {
action {
when (categoryModel) {
null -> return#action
else -> dbController.updateCategory(categoryModel)
}
categoryTable.tableView.refresh()
}
}
}
tableview<CategoryModel> {
categoryTable = editModel
items = categories
enableCellEditing()
enableDirtyTracking()
onUserSelect() {
//open a dialog
}
//DOES WORK
categoryModel.rebindOnChange(this) { selectedItem ->
item = selectedItem?.item ?: CategoryModel().item
}
// Question #2. why bindSelected does not work, and i have to do it like above
//DOES NOT WORK
// bindSelected(categoryModel)
//
column("Name", CategoryModel::name).makeEditable()
column("Description", CategoryModel::description).makeEditable()
}
}
right = form {
fieldset {
field("Name") {
textfield(categoryModel.name)
}
}
fieldset {
field("Description") {
textfield(categoryModel.description)
}
}
button("ADD CATEGORY") {
action {
dbController.addCategory(categoryModel.name.value, categoryModel.description.value)
}
}
}
}
}
I apologize for huge amount of code, also in last code snipped i left questions in form of comments where i fail to achive desired results.
I am sure i am not properly binding code, i just dont see why, also i sometimes use one variable to update data, my declared one "categoryModel" and sometimes i use tableview.selecteditem, it just seems hacky and i cant seem to grasp way.
Thank you!

How to access global telerik functions in typescript

I try to access the function GetRadWindowManager() from my app.ts file.
I added the definitions files and I cannot find a way to call "window.GetRadWindowManager()" or "window.top.GetRadWindowManager()"
That is my code until now :
export class App {
private _windowManager: Telerik.Web.UI.RadWindowManager;
constructor() {
this._windowManager = null;
}
getRadWindowManager(): Telerik.Web.UI.RadWindowManager {
if (this._windowManager == null) {
try {
this._windowManager = window.top.GetRadWindowManager();
} catch (err) {
this._windowManager = GetRadWindowManager();
}
}
return this._windowManager;
}
}
PS : Don't mind the try/catch block, I'll remove that later :)
Thanks for your help !
Well, I don't know if this answer is the best, but extending the Window object allowed me to manually add this function. Then I can simply call it from my script.ts
interface Window {
GetRadWindowManager(): Telerik.Web.UI.RadWindowManager;
}

Swashbuckle rename Data Type in Model

I'm putting together a web API that needs to match an external sources XML format and was looking to rename the Data Type objects in the swagger output.
It's working fine on the members of the class but I was wondering if it was possible to override the class name as well.
Example:
[DataContract(Name="OVERRIDECLASSNAME")]
public class TestItem
{
[DataMember(Name="OVERRIDETHIS")]
public string toOverride {get; set;}
}
In the generated output I end up seeing
Model:
TestItem {
OVERRIDETHIS (string, optional)
}
I'd hope to see
OVERRIDECLASSNAME {
OVERRIDETHIS (string, optional)
}
Is this possible?
Thanks,
I had the same problem and I think I solved it now.
First of all add SchemaId in Swagger Configuration (from version 5.2.2 see https://github.com/domaindrivendev/Swashbuckle/issues/457):
GlobalConfiguration.Configuration
.EnableSwagger(c =>
{
c.SchemaId(schemaIdStrategy);
[...]
}
Then add this method:
private static string schemaIdStrategy(Type currentClass)
{
string returnedValue = currentClass.Name;
foreach (var customAttributeData in currentClass.CustomAttributes)
{
if (customAttributeData.AttributeType.Name.ToLower() == "datacontractattribute")
{
foreach (var argument in customAttributeData.NamedArguments)
{
if (argument.MemberName.ToLower() == "name")
{
returnedValue = argument.TypedValue.Value.ToString();
}
}
}
}
return returnedValue;
}
Hope it helps.
Pretty old question, but as I was looking for a similar solution, I bumped into this.
I think the code in Vincent's answer might not work.
Here is my take on it:
private static string schemaIdStrategy(Type currentClass)
{
var dataContractAttribute = currentClass.GetCustomAttribute<DataContractAttribute>();
return dataContractAttribute != null && dataContractAttribute.Name != null ? dataContractAttribute.Name : currentClass.Name;
}
Adding to the thread as I am not able to use the answer with Swashbukle for AspNetCore.
I am doing this. However I am not totally happy as if the object is contain in another object it is showing its original name. For example if you have a result set that is Paged That result is shown incorrectly.So this is not a final answer but might work on simple use cases.
I am using a Schema Filter. And the object just have [JsonObject(Title="CustomName")] as I get the Title property for the data type.
First Define a class like this:
public class CustomNameSchema : ISchemaFilter
{
public void Apply(Schema schema, SchemaFilterContext context)
{
if (schema?.Properties == null)
{
return;
}
var objAttribute = context.SystemType.GetCustomAttribute<JsonObjectAttribute>();
if( objAttribute!= default && objAttribute?.Title?.Length > 0)
{
schema.Title = objAttribute.Title;
}
}
}
On the startup you must configure a SchemaFilter
c.SchemaFilter<CustomNameSchema>();

Thymeleaf at syntax: "#{/}" returns empty if I include ResourceUrlEncodingFilter

I'm using Thymeleaf.
This template:
<a th:href="#{/}">a</a>
produces this html:
a
This is what I'm expected.
I put ResourceUrlEncodingFilter bean to try ContentVersionStrategy in my WebMvcConfigurerAdapter extended class.
#Bean
public ResourceUrlEncodingFilter resourceUrlEncodingFilter() {
return new ResourceUrlEncodingFilter();
}
The produced html turned to:
a
The value of href is empty.
I hope href is "/" even if I put ResourceUrlEncodingFilter bean.
th:href="#{/a}" turns to href="/a" in both cases.
Did I do something wrong?
Thank you very much.
UPDATE:
This is my build.gradle
buildscript {
repositories {
jcenter()
}
dependencies {
classpath 'io.spring.gradle:dependency-management-plugin:0.5.1.RELEASE'
classpath("org.springframework.boot:spring-boot-gradle-plugin:1.2.3.RELEASE")
}
}
apply plugin: 'java'
apply plugin: 'eclipse'
apply plugin: 'spring-boot'
apply plugin: 'io.spring.dependency-management'
version = '1.0'
jar {
manifest {
attributes 'Implementation-Title': 'Gradle Quickstart', 'Implementation-Version': version
}
}
repositories {
mavenCentral()
}
dependencyManagement {
imports {
mavenBom 'io.spring.platform:platform-bom:1.1.2.RELEASE'
}
}
dependencies {
compile('org.webjars:bootstrap:3.3.1')
compile('org.webjars:knockout:3.2.0')
compile('org.webjars:momentjs:2.9.0')
compile('org.webjars:numeral-js:1.5.3-1')
compile('org.webjars:underscorejs:1.7.0-1')
compile('org.webjars:sugar:1.4.1')
compile('org.webjars:jqplot:1.0.8r1250')
compile('org.webjars:jquery-cookie:1.4.1-1')
compile("org.springframework.boot:spring-boot-starter-actuator")
compile("org.springframework.boot:spring-boot-starter-batch")
compile("org.springframework.boot:spring-boot-starter-data-jpa")
compile("org.springframework.boot:spring-boot-starter-security")
compile("org.springframework.boot:spring-boot-starter-web")
compile("org.springframework.boot:spring-boot-starter-tomcat")
compile("org.springframework.boot:spring-boot-starter-thymeleaf")
compile("org.springframework.boot:spring-boot-starter-test")
compile("org.springframework:spring-context-support") // this is for mail
compile('commons-codec:commons-codec')
compile("commons-io:commons-io")
compile('com.google.guava:guava')
compile('org.hibernate:hibernate-validator')
compile("com.sun.mail:javax.mail")
compile('mysql:mysql-connector-java')
compile("org.yaml:snakeyaml")
compile("org.apache.commons:commons-lang3:3.2")
compile('com.amazonaws:aws-java-sdk:1.9.4')
compile('net.sf.supercsv:super-csv:2.2.0')
compile('edu.vt.middleware:vt-password:3.1.2')
}
test {
//systemProperties 'property': 'value'
systemProperties 'spring.profiles.active': 'unittest'
systemProperties 'MAIL_PROP': 'mail.properties'
systemProperties 'user.timezone': 'UTC'
}
uploadArchives {
repositories {
flatDir {
dirs 'repos'
}
}
}
Thanks for this detailed explanation and the repro project!
This is actually a bug: see SPR-13241, to be fixed in Spring 4.1.8 and 4.2.0.
Spring Boot adds "/**" matcher for automatic configurations of static web resources locations.
The locations are /META-INF/resources/, /resources/, /static/ and /public/.
When you put below html in Thymeleaf template,
<a th:href="#{/}">a</a>
Below method in ResourceUrlProvider.java is called because of the matcher and get into for loop:
public final String getForLookupPath(String lookupPath) {
// -- omission --
for(String pattern : matchingPatterns) {
// -- omission --
String pathWithinMapping = getPathMatcher().extractPathWithinPattern(pattern, lookupPath);
String pathMapping = lookupPath.substring(0, lookupPath.indexOf(pathWithinMapping));
// -- omission --
String resolved = chain.resolveUrlPath(pathWithinMapping, handler.getLocations());
if (resolved == null) {
continue;
}
// -- omission --
return pathMapping + resolved;
}
// -- omission --
}
The argument, lookupPath is "/" by the "#{/}", Then:
The pathWithinMapping will be "".
The pathMapping will be "".
The resolved will be "".
So this method returns "" and the value is set to href="".
This is in my opinion, if the pathWithinMapping is "", to continue the for loop seems good. Calling chain.resolveUrlPath seems not good.
Thanks,

Unload Plugin in Qt

Issue comes up when i try to unload plugin that is loaded and load a new one. So both plugins are loaded correctly, but when switching them (first is loaded, second is unloaded and viceversa) my app crashes. What can be the problem ?
First what i'm doing i try to unload a plugin stored into a QList of QPluginLoader, then i check (depdend on id(integer number) passed from a special menu for loading plugins ) what plugin to load. First load is well (first plugin is loaded, nothing at this point to unload) , second load (unload first plugin, second is loaded), at third load i get crash
void MainWindow::loadPluginUsingId (int plugin_id) {
foreach (QPluginLoader* pluginLoader, plugins) {
pluginLoader->unload();
delete pluginLoader;
}
switch (plugin_id) {
case 0 : {
foreach (QString fileName, pluginDir.entryList(QDir::Files)) {
if (fileName == fullNameOfPlugins.value(plugin_id)) {
QPluginLoader* pluginLoader = new QPluginLoader(pluginDir.absoluteFilePath(fileName));
QObject *plugin = pluginLoader->instance();
IndicatorInterface *indicator = qobject_cast<IndicatorInterface*>(plugin);
indicator->initIndicator();
plugins.append(pluginLoader);
}
}
}
break;
case 1 : {
foreach (QString fileName, pluginDir.entryList(QDir::Files)) {
if (fileName == fullNameOfPlugins.value(plugin_id)) {
QPluginLoader* pluginLoader = new QPluginLoader(pluginDir.absoluteFilePath(fileName));
QObject* plugin = pluginLoader->instance();
PlotterInterface *plotter = qobject_cast<PlotterInterface*>(plugin);
plotter->initPlotter();
plugins.append(pluginLoader);
}
}
}
break;
default :
break;
}
}
foreach (QPluginLoader* pluginLoader, plugins) {
pluginLoader->unload();
delete pluginLoader; // this could be your problem
}
You need to remove the dangling pointer from the plugins list. Failure to do that would result in what you're describing.
Try this:
while (!plugins.isEmpty()) {
QPluginLoader* pluginLoader = plugins.takeFirst();
pluginLoader->unload();
delete pluginLoader;
}

Resources