Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,4 @@ target/
classes/
*.iml
.idea
test
1 change: 1 addition & 0 deletions OWNER.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Andrey Upshinskiy
88 changes: 80 additions & 8 deletions src/main/java/track/container/Container.java
Original file line number Diff line number Diff line change
@@ -1,34 +1,106 @@
package track.container;

import java.util.List;

import track.container.config.Bean;
import track.container.config.InvalidConfigurationException;
import track.container.config.Property;

import java.beans.PropertyEditor;
import java.beans.PropertyEditorManager;
import java.io.File;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
* Основной класс контейнера
* У него определено 2 публичных метода, можете дописывать свои методы и конструкторы
*/
public class Container {
private Map<String, Bean> beansById = new HashMap();
private Map<String, Bean> beansByClassName = new HashMap();
private Map<Bean, Object> objByBean = new HashMap();


// Реализуйте этот конструктор, используется в тестах!
public Container(List<Bean> beans) {
for (Bean bean: beans) {
this.beansById.put(bean.getId(), bean);
this.beansByClassName.put(bean.getClassName(), bean);
}
}

public Container(String configFileName) throws InvalidConfigurationException {
this((new JsonConfigReader()).parseBeans(new File(Main.class.getClassLoader()
.getResource(configFileName).getFile())));
}

private String getSetMethodName(String fieldName) {
return "set" + Character.toUpperCase(fieldName.charAt(0)) + fieldName.substring(1);
}

private void createObject(Bean bean) throws ClassNotFoundException,
IllegalAccessException, InstantiationException, NoSuchFieldException,
NoSuchMethodException, InvocationTargetException {
Class clazz = Class.forName(bean.getClassName());
Object object = clazz.newInstance();
objByBean.put(bean, object);

for (Property property: bean.getProperties().values()) {
Field field = clazz.getDeclaredField(property.getName());
Class type = field.getType();
Method set = clazz.getMethod(getSetMethodName(property.getName()), type);
Copy link
Copy Markdown
Collaborator

@asabelnikova asabelnikova Nov 16, 2016

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

если у поля не будет сеттера мы не проставим поле?
можно через рефлекшен напрямую выставлять значение поля


switch (property.getType()) {
case VAL:
PropertyEditor editor = PropertyEditorManager.findEditor(type);
editor.setAsText(property.getValue());
set.invoke(object, editor.getValue());
break;
case REF:
if (!objByBean.containsKey(beansById.get(property.getValue()))) {
createObject(beansById.get(property.getValue()));
}
set.invoke(object, objByBean.get(beansById.get(property.getValue())));
break;
default:
break;
}
}
}

private Object getByBean(Bean bean) throws ClassNotFoundException,
InstantiationException, IllegalAccessException, NoSuchMethodException,
NoSuchFieldException, InvocationTargetException {
if (bean == null) {
return null;
}

if (!objByBean.containsKey(bean)) {
createObject(bean);
}

return objByBean.get(bean);
}

/**
* Вернуть объект по имени бина из конфига
* Например, Car car = (Car) container.getById("carBean")
*/
public Object getById(String id) {
return null;
public Object getById(String id) throws ClassNotFoundException,
IllegalAccessException, InstantiationException, NoSuchMethodException,
NoSuchFieldException, InvocationTargetException {
return getByBean(beansById.get(id));
}

/**
* Вернуть объект по имени класса
* Например, Car car = (Car) container.getByClass("track.container.beans.Car")
*/
public Object getByClass(String className) {
return null;
public Object getByClass(String className) throws ClassNotFoundException,
IllegalAccessException, InstantiationException, NoSuchMethodException,
NoSuchFieldException, InvocationTargetException {

return getByBean(beansByClassName.get(className));
}
}
80 changes: 75 additions & 5 deletions src/main/java/track/container/JsonConfigReader.java
Original file line number Diff line number Diff line change
@@ -1,19 +1,89 @@
package track.container;

import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import track.container.config.*;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

import track.container.config.Bean;
import track.container.config.ConfigReader;
import track.container.config.InvalidConfigurationException;
import java.util.Map;

/**
* TODO: Реализовать
*/
public class JsonConfigReader implements ConfigReader {

private Property parseProperty(JsonNode property) throws InvalidConfigurationException {
if (!property.has("name")) {
throw new InvalidConfigurationException("There is no field \"name\" in property" +
", but it must be here");
}
if (!(property.has("type"))) {
throw new InvalidConfigurationException("There is no field \"type\" in property" +
", but it must be here");
}
if (!(property.has("value"))) {
throw new InvalidConfigurationException("There is no field \"type\" in property" +
", but it must be here");
}

String name = property.get("name").asText();

ValueType type;
String value = property.get("value").asText();
if (property.get("type").asText().equals("REF")) {
type = ValueType.REF;
} else {
type = ValueType.VAL;
}

return new Property(name, value, type);
}

private Bean parseBean(JsonNode bean) throws InvalidConfigurationException {
if (!bean.has("id")) {
throw new InvalidConfigurationException("There is no field \"id\", but it must be here");
}
if (!bean.has("className")) {
throw new InvalidConfigurationException("There is no field \"className\", but it must be here");
}
if (!bean.has("properties")) {
throw new InvalidConfigurationException("There is no field \"properties\", but it must be here");
}

String id = bean.get("id").asText();
String className = bean.get("className").asText();
Map<String, Property> properties = new HashMap();

for (JsonNode property: bean.get("properties")) {
Property parsedProperty = parseProperty(property);
properties.put(parsedProperty.getName(), parsedProperty);
}

return new Bean(id, className, properties);
}

@Override
public List<Bean> parseBeans(File configFile) throws InvalidConfigurationException {
return null;
ObjectMapper objectMapper = new ObjectMapper();
JsonNode root = null;
try {
root = objectMapper.readTree(configFile);
} catch (IOException e) {
e.printStackTrace();
}
if (!root.has("beans")) {
throw new InvalidConfigurationException("There is no field \"beans\", but it must be here");
}
List<Bean> beans = new ArrayList();

for (JsonNode bean: root.get("beans")) {
beans.add(parseBean(bean));
}

return beans;
}
}
24 changes: 17 additions & 7 deletions src/main/java/track/container/Main.java
Original file line number Diff line number Diff line change
@@ -1,25 +1,35 @@
package track.container;

import track.container.beans.Car;
import track.container.config.InvalidConfigurationException;

import java.lang.reflect.InvocationTargetException;

/**
*
*/
public class Main {

public static void main(String[] args) {
public static void main(String[] args) throws IllegalAccessException, InvocationTargetException,
InstantiationException, NoSuchFieldException, NoSuchMethodException, ClassNotFoundException {

/*

ПРИМЕР ИСПОЛЬЗОВАНИЯ

*/

// // При чтении нужно обработать исключение
// ConfigReader reader = new JsonReader();
// List<Bean> beans = reader.parseBeans("config.json");
// Container container = new Container(beans);
// При чтении нужно обработать исключение

Container container = null;
try {
container = new Container("config.json");
} catch (InvalidConfigurationException e) {
e.printStackTrace();
}
//
// Car car = (Car) container.getByClass("track.container.beans.Car");
// car = (Car) container.getById("carBean");
Car car = (Car) container.getByClass("track.container.beans.Car");
car = (Car) container.getById("carBean");


}
Expand Down
12 changes: 9 additions & 3 deletions src/main/java/track/lessons/lesson2/Document.java
Original file line number Diff line number Diff line change
@@ -1,20 +1,26 @@
package track.lessons.lesson2;

import java.util.Arrays;

/**
*
*/
public class Document {
String[] tokens;

Document(String[] newTokens) {
tokens = newTokens;
}

String[] getTokens() {
return null;
return tokens;
}

int getTokenCount() {
return 0;
return tokens.length;
}

boolean hasToken(String token) {
return false;
return Arrays.stream(tokens).anyMatch(token::equals);
}
}
17 changes: 10 additions & 7 deletions src/main/java/track/lessons/lesson2/Parser.java
Original file line number Diff line number Diff line change
Expand Up @@ -9,19 +9,22 @@
public class Parser {

Document parse(String data) {
return null;
return new Document(data.split(" "));
}

public static void main(String[] args) throws Exception {

String path = "path/to/file";
String path = "./test";
BufferedReader reader = new BufferedReader(new FileReader(path));
// reader умеет читать по строкам с помощью метода readLine()

// Создайте объект Parser

// Получите объект Document, реализовав метод parse()
StringBuilder stringBuilder = new StringBuilder();
String buffer;

while ((buffer = reader.readLine()) != null) {
stringBuilder.append(buffer);
stringBuilder.append(" ");
}

Parser parser = new Parser();
Document doc = parser.parse(stringBuilder.toString());
}
}
50 changes: 49 additions & 1 deletion src/main/java/track/lessons/lesson3/DynamicList.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,53 @@
/**
*
*/
public class DynamicList {
public class DynamicList extends List {
private static final int DEFAULT_SIZE = 16;
private int length = 0;
private int bufferSize = DEFAULT_SIZE;
private int[] buffer = new int[bufferSize];

private void reallocate(int newSize) {
int[] newBuffer = new int[newSize];
System.arraycopy(buffer, 0, newBuffer, 0, length);
buffer = newBuffer;
bufferSize = newSize;
}

@Override
public void add(int item) {
if (length == bufferSize) {
reallocate(bufferSize * 2);
}

buffer[length++] = item;
}

@Override
public int remove(int idx) {
if (idx < 0 || idx >= length) {
printLengthError();
return 0;
}

if (length * 4 <= bufferSize) {
reallocate(bufferSize / 2);
}

length--;
int item = buffer[idx];
System.arraycopy(buffer, idx + 1, buffer, idx, length - idx);

return item;
}

@Override
public int get(int idx) {
return buffer[idx];
}

@Override
public int size() {
return length;
}
}
Loading